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);
?>
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());
}
});
}
});
}
//...