Search code examples
javaandroidokhttp

OkHttp - Android get Data from MySQL database


Hey Im fairly new to android developing and Im currently trying to establish a connection to my database so I can work with the data on my phone.

Im using OkHttp and mysqli with php.

I wrote a handler which accesses the .php pages and makes the database calls.

public class OkHttpHandler extends AsyncTask<String, Void, String> {

private OkHttpClient client = null;

public String latestMessage = "";

public OkHttpHandler(){

    client = new OkHttpClient();
}

@Override
protected String doInBackground(String... params) {
    Request.Builder builder = new Request.Builder();
    builder.url(params[0].toString());
    Request request = builder.build();

    try{
        Response response = client.newCall(request).execute();
        latestMessage = response.body().string();
        return response.body().string();
    } catch(Exception e){
        e.printStackTrace();
    }

    //latestMessage = "failed";
    return null;
}

And I want to do something like this:

    public int getSongwriterId(String songwriter) {
    OkHttpHandler okHttpHandler = new OkHttpHandler();
    okHttpHandler.execute(url_get_songwriter_id + "?songwriter=" + songwriter);
    String responseString = "";
    while(responseString == "") {
        responseString = okHttpHandler.latestMessage;
    }
    okHttpHandler.cancel(true);
    Songwriter s = getSongwriterFromJSON(responseString);

    return s.getId();
    }

Now, I know that this ugly while(true) is a shitty solution. But how should I do it so Im 100% certain I got my responseString before passing it into "getSongwriterFromJSON"? I really don't get how that is supposed to work.

The code works all fine when i debug it step by step, but the application just blackscreens from time to time without debug. I guess thats due to the while(true) loop and that probably just runs and runs and clocks up the thread so that my background thread just dies - I really don't know anymore.

Please if you provide help, explain what Im doing wrong, and how I should do it right. Thanks.

Edit php file used:

<?php
$response = array();

$con = @mysqli_connect("XXX", "XXX", "XXX", "XXX");

if (mysqli_connect_errno())
{
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

$sql = "Select * FROM songwriter ";
$sql .= "where composerName = '";
$sql .= $_GET["songwriter"];
$sql .= "'";

$query = mysqli_query($con,$sql);

// looping through all results
$response["songwriter"] = array();

while ($row = mysqli_fetch_array($query)) {
    $songwriter = array();
    $songwriter["id"] = $row["id"];
    $songwriter["composerName"] = $row["composerName"];
    $songwriter["arrangerName"] = $row["arrangerName"];

    // push single product into final response array
    array_push($response["songwriter"], $songwriter);
}

// echoing JSON response
echo json_encode($response);
?>

Solution

  • You're using the sync API of OkHttp while there is an async one, that you should use:

    That while is a serious bottleneck, you should remove it asap. Try something like this:

    Request.java

    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.OkHttpClient;
    import okhttp3.RequestBody;
    import okhttp3.Response;
    
    /** Very basic Request helper **/
    public class Request {
    
        public static OkHttpClient client = null;
    
        /**
          * Get the current OkHttpClient or creates a new one if it doesn't exists
          * @return OkHttpClient
          */
    
       public static OkHttpClient getClient(){
    
            if(client == null)
                client = new OkHttpClient();
    
            return client;
       }
    
        public Call get(String url, Callback callback) {
    
           okhttp3.Request request = new okhttp3.Request.Builder()
              .url(url)
              .get()
              .build();
    
           Call call = getClient().newCall(request);
           call.enqueue(callback);
    
           return call;
    
        }
    }
    

    Activity

    //...
    public interface MyCallback {
       void run(Object data); //Generic callback
    }
    
    
    public void getSongwriterId(String songwriter, MyCallback myCallback) {
    
    
       Request.get(url_get_songwriter_id + "?songwriter=" + songwriter, new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {
            //Handle error
          }
    
          @Override
          public void onResponse(Call call, final Response response) throws IOException {
    
             final String body = response.body().string(); //Get API response
    
             final Songwriter s = getSongwriterFromJSON(body);
    
             //Remove it if you just need to show the ID in the UI
             myCallback.run(s.getId())
    
             //OKHttp callback isn't in the main thread, 
             //UI operations need to be run in the main thread
             //That's why you should use runOnUiThread
             MyActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //Handle UI here if needed           
                    ((TextView) findViewById(R.id.myTextView)).setText(s.getId());
    
                }
             });
          }
       });
    }
    //...