Reputation: 351
Now in my app i try to do http parsing from url, but i didn't carry about threads, before this time...
I have such class and method:
public class TwitterOAuthHelper {
public String httpQueryToApi(String url) {
HttpGet get = new HttpGet(url);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setUseExpectContinue(params, false);
get.setParams(params);
String response = null;
try {
SharedPreferences settings = context.getSharedPreferences("my_app", 0);
String userKey = settings.getString("user_key", "");
String userSecret = settings.getString("user_secret", "");
consumer.setTokenWithSecret(userKey, userSecret);
consumer.sign(get);
DefaultHttpClient client = new DefaultHttpClient();
response = client.execute(get, new BasicResponseHandler());
} catch (Exception e) {
displayToast("Failed to get data.");
}
return response;
}
}
and now i try to move this logic into asyncTask:
String result;
public String httpQueryToApi(String url) {
new AsyncTask<String,Void,String>(){
@Override
protected String doInBackground(String... params) {
HttpGet get = new HttpGet(String.valueOf(params));
HttpParams param = new BasicHttpParams();
HttpProtocolParams.setUseExpectContinue(param, false);
get.setParams(param);
String response = null;
try {
SharedPreferences settings = context.getSharedPreferences("my_app", 0);
String userKey = settings.getString("user_key", "");
String userSecret = settings.getString("user_secret", "");
consumer.setTokenWithSecret(userKey, userSecret);
consumer.sign(get);
DefaultHttpClient client = new DefaultHttpClient();
response = client.execute(get, new BasicResponseHandler());
} catch (Exception e) {
displayToast("Failed to get data.");
}
result = response;
return response;
}
}.execute(url);
return result;
}
but how can i return my response result value to method?
what is the best practice of doing that?
Upvotes: 1
Views: 2204
Reputation: 19243
dd below method to asynctask body (below doInBackground
method):
@Override
protected void onPostExecute(String result) {
// result is your returned value from doInBackground
// now we are in main ui thread
}
If you want a callback to antoher method it should be interface
public interface ResultInterface {
public void resultFromHttp(String result);
}
then your method
public String httpQueryToApi(String url, final ResultInterface ri){
//as bove
@Override
protected void onPostExecute(String result) {
if(ri!=null)
ri.resultFromHttp(result);
}
}
implement ResultInterface
in your Activity
/Fragment
/whatever is calling httpQueryToApi
, pass this
as second param (ri
interface)
Upvotes: 4
Reputation: 5672
1) Create separate class for you Async (not anonymous).
2) Create interface class.
public interface AsyncResponse {
void onProcessFinish(String output);
}
3) In your Async class, you need to declare it (interface : AsyncResponse):
public class MyAsyncTask extends AsyncTask<String,Void,String>(){
public AsyncResponse listener = null;
public MyAsyncTask(AsyncResponse l) {
this.listener = l;
}
{...}
@Override
protected String doInBackground(String... params) {
HttpGet get = new HttpGet(String.valueOf(params));
HttpParams param = new BasicHttpParams();
HttpProtocolParams.setUseExpectContinue(param, false);
get.setParams(param);
String response = null;
try {
SharedPreferences settings = context.getSharedPreferences("my_app", 0);
String userKey = settings.getString("user_key", "");
String userSecret = settings.getString("user_secret", "");
consumer.setTokenWithSecret(userKey, userSecret);
consumer.sign(get);
DefaultHttpClient client = new DefaultHttpClient();
response = client.execute(get, new BasicResponseHandler());
} catch (Exception e) {
displayToast("Failed to get data.");
}
result = response;
return response;
}
@Override
protected void onPostExecute(String result) {
listener.onProcessFinish(result);
}
}
4) In your class (where you call AssyncClass, for example in your Activity) you need to implements interface you created earlier AsyncResponse.
public class MainActivity implements AsyncResponse{
{...}
void onProcessFinish(String output){
//this you will received result fired from async class of onPostExecute(result) method.
}
}
6) now you can call in MainActivity:
new MyAsyncTask(this).execute("your_url");
Upvotes: 0
Reputation: 1750
Initially your function returned a string which you then further processed. Fine. But you can not use threading like that. You can not return result from the function, because it has not been set yet (well you can but it will return null). The correct way of doing this is
public void httpQueryToApi(String url) {
new AsyncTask<String,Void,String>(){
@Override
protected String doInBackground(String... params) {
HttpGet get = new HttpGet(String.valueOf(params));
HttpParams param = new BasicHttpParams();
HttpProtocolParams.setUseExpectContinue(param, false);
get.setParams(param);
String response = null;
try {
SharedPreferences settings = context.getSharedPreferences("my_app", 0);
String userKey = settings.getString("user_key", "");
String userSecret = settings.getString("user_secret", "");
consumer.setTokenWithSecret(userKey, userSecret);
consumer.sign(get);
DefaultHttpClient client = new DefaultHttpClient();
response = client.execute(get, new BasicResponseHandler());
} catch (Exception e) {
displayToast("Failed to get data.");
}
return response;
}
@Override
protected void onPostExecute(String s) {
//here s is the response string, do what ever you want
super.onPostExecute(s);
}
}.execute(url);
}
You will have to shift your further processing logic to onPostExecute, no other way :) If you want do dig a little deeper look into Future<>
Upvotes: 0
Reputation: 1029
You can't since the Task will be executed in another thread.
However you could use a callback to get the result. Take a look at: https://stackoverflow.com/a/19520293/4299154.
Upvotes: 0