Reputation: 2252
I've created an AsyncTask class to handle sending and receiving from my server. What I'm trying to do is fire an event or callback when the data is received so I can use said data to manipulate the UI.
AsyncTask class:
public class DataCollectClass extends AsyncTask<Object, Void, JSONObject> {
private JSONObject collected;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//@Override -Commented out because it doesn't like the override
protected void onPostExecute() {
try {
Log.d("Net", this.collected.getString("message"));
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
protected JSONObject doInBackground(Object... params) {
OkHttpClient client = new OkHttpClient();
// Get Parameters //
String requestURI = (String) params[0];
RequestBody formParameters = (RequestBody) params[1];
Request request = new Request.Builder().url(requestURI).post(formParameters).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// DO something on FAIL
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String jsonResponse = response.body().string();
Log.d("Net", jsonResponse);
try {
DataCollectClass.this.collected = new JSONObject(jsonResponse);
Log.d("Net", DataCollectClass.this.collected.getString("message"));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return collected;
}
}
This is working, it prints an expected line of JSON into the log.
It's called from the Activity as:
new DataCollectClass().execute(requestURI, formVars);
I've looked all over, and I can't seem to find a definitive answer on how (and where) to add a callback. Preferably, the callback code itself should be with the DataCollectClass
so all related code is reusable in the same place.
Is there a way to create a custom event firing (similar to Javascript libraries) that the program can listen for?
I've been pulling my hair out over this!
UPDATE:
Since AsyncTask is redundant, I've removed it and rewrote the code (in case someone else has this same issue):
public class DataCollectClass { private JSONObject collected;
public interface OnDataCollectedCallback {
void onDataCollected(JSONObject data);
}
private OnDataCollectedCallback mCallback;
public DataCollectClass(OnDataCollectedCallback callback, String requestURI, RequestBody formParameters){
mCallback = callback;
this.collect(requestURI, formParameters);
}
public JSONObject collect(String requestURI, RequestBody formParameters) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(requestURI).post(formParameters).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//TODO Add what happens when shit fucks up...
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String jsonResponse = response.body().string();
Log.d("Net", jsonResponse);
try {
DataCollectClass.this.collected = new JSONObject(jsonResponse);
if(mCallback != null)
mCallback.onDataCollected(DataCollectClass.this.collected);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return collected;
}
}
Called from Activity:
new DataCollectClass(new DataCollectClass.OnDataCollectedCallback() {
@Override
public void onDataCollected(JSONObject data) {
if(data != null) {
try {
// Do Something //
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, requestURI, formVars);
All working perfectly! Thanks!
Upvotes: 2
Views: 1813
Reputation: 3389
If you want to utilize a callback for an AsyncTask you can handle it via the following.
Do something like this (modifying your code to add what is below)
public class DataCollectClass extends AsyncTask<Object, Void, JSONObject> {
public interface OnDataCollectedCallback{
void onDataCollected(JSONObject data);
}
private OnDataCollectedCallback mCallback;
public DataCollectClass(OnDataCollectedCallback callback){
mCallback = callback;
}
// your code that is already there
...
@Override
public onPostExecute(JSONObject response){
if(mCallback != null)
mCallback.onDataCollected(response);
}
}
Then to make the magic happen
new DataCollectClass(new OnDataCollectedCallback() {
@Override
public void onDataCollected(JSONObject data) {
if(data != null)
// DO something with your data
}
}).execute(requestURI, formVars);
However, it is worth noting, most networking libraries, including OkHttp, handle background threads internally, and include callbacks to utilize with the requests.
This also implements a custom interface, so others may be able to see how you could use this for any AsyncTask.
Upvotes: 1
Reputation: 7065
Call Webservice using asynctask is an old fashioned. You can use Volley or retrofit. But you can use this process to call Webservice . Here is steps:
Create an Interface and implements it in your Activity/Fragment
public interface IAsynchronousTask {
public void showProgressBar();
public void hideProgressBar();
public Object doInBackground();
public void processDataAfterDownload(Object data);
}
Create Class DownloadableAsyncTask
. This class is:
import android.os.AsyncTask;
import android.util.Log;
public class DownloadableAsyncTask extends AsyncTask<Void, Void, Object> {
IAsynchronousTask asynchronousTask;
public DownloadableAsyncTask(IAsynchronousTask activity) {
this.asynchronousTask = activity;
}
@Override
protected void onPreExecute() {
if (asynchronousTask != null)
asynchronousTask.showProgressBar();
}
@Override
protected Object doInBackground(Void... params) {
try {
if (asynchronousTask != null) {
return asynchronousTask.doInBackground();
}
} catch (Exception ex) {
Log.d("BSS", ex.getMessage()==null?"":ex.getMessage());
}
return null;
}
@Override
protected void onPostExecute(Object result) {
if (asynchronousTask != null) {
asynchronousTask.hideProgressBar();
asynchronousTask.processDataAfterDownload(result);
}
}
}
Now in your Activity you will find this methods.
DownloadableAsyncTask downloadAsyncTask;
ProgressDialog dialog;
private void loadInformation() {
if (downloadAsyncTask != null)
downloadAsyncTask.cancel(true);
downloadAsyncTask = new DownloadableAsyncTask(this);
downloadAsyncTask.execute();
}
@Override
public void showProgressBar() {
dialog = new ProgressDialog(this, ProgressDialog.THEME_HOLO_LIGHT);
dialog.setMessage(" Plaese wait...");
dialog.setCancelable(false);
dialog.show();
}
@Override
public void hideProgressBar() {
dialog.dismiss();
}
@Override
public Object doInBackground() {
// Call your Web service and return value
}
@Override
public void processDataAfterDownload(Object data) {
if (data != null) {
// data is here
}else{
//"Internal Server Error!!!"
}
}
Now just call loadInformation()
method then you will get your response on processDataAfterDownload()
.
Upvotes: 0
Reputation: 191728
There is a asynchronous get in OkHttp, so you don't need an AsyncTask, but as a learning exercise, you could define your callback as a parameter something like so.
new DataCollectClass(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// DO something on FAIL
}
@Override
public void onResponse(Call call, Response response) throws IOException {
JSONObject collected = null;
String jsonResponse = response.body().string();
Log.d("Callback - Net", jsonResponse);
try {
collected = new JSONObject(jsonResponse);
Log.d("Callback - Net", collected.getString("message"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}).execute(requestURI, formVars);
The AsyncTask
public class DataCollectClass extends AsyncTask<Object, Void, Call> {
private Callback mCallback;
private OkHttpClient client;
public DataCollectClass(Callback callback) {
this.mCallback = callback;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
this.client = new OkHttpClient();
}
@Override
protected void onPostExecute(Call response) {
if (response != null && this.mCallback != null) {
response.enqueue(this.mCallback);
}
}
@Override
protected Call doInBackground(Object... params) {
// Get Parameters //
String requestURI = (String) params[0];
RequestBody formParameters = (RequestBody) params[1];
Request request = new Request.Builder().url(requestURI).post(formParameters).build();
return client.newCall(request); // returns to onPostExecute
}
}
Upvotes: 1