我已经实现了一种将onPostExecute
的结果返回到我的主要活动的方法。我想知道这是否是我做的正确的事情,是否有更多机会改进它,如果它不是最好的方式,最好的方法是什么?
这就是我所做的:
public class MainClass implements AsyncResponse {
private MyAsyncTask asyncTask;
public MainClass() {
asyncTask = new MyAsyncTask();
asyncTask.asyncResponse = this;
}
public void startTask( {
asyncTask.execute("string");
}
@Override
public void processDone(String res) {
// got response in MainClass from onPostExecute
}
private class MyAsyncTask extends AsyncTask<String, String, String> {
protected AsyncResponse asyncResponse = null;
@Override
protected String doInBackground(String... urls) {
return "some processed string";
}
@Override
protected void onPostExecute(String res) {
this.asyncResponse.processDone(res);
}
}
}
这是AsyncResponse
界面:
public interface AsyncResponse {
void processDone(String res);
}
我想知道在平均Android移动设备上的处理速度,这是一个好方法,如果没有,我如何改进它,使其成为一个好方法?
感谢。
答案 0 :(得分:0)
我总是这样做,从来没有任何问题。我会说这是最好的方式。
答案 1 :(得分:0)
在一行中没有任何回调
String s= new MyAsyncTask().execute().get();
答案 2 :(得分:0)
您添加了一个不必要的界面 - 也许这会使您的代码不太可用。
首先,如果您在AsyncTask
中创建Activity
作为类,则不需要该接口。你可以这样做:
@Override
protected void onPostExecute(String res) {
processDone(res);
}
AsyncTask
将在UI线程上执行onPostExecute
,您可以在没有接口的情况下调用Activity
方法。
其次,如果你在AsyncTask
类之外创建Activity
(例如,在它自己的java文件中),那么你可以使用这个方法,除了它不是一个好主意,因为它将持有在另一个线程上引用Activity
- 这是内存泄漏风险。
为了避免这种情况,您的界面应该在一个单独的类中实现,例如传递给AsyncTaskResponse.java
类的AsyncTask
。
最后,AsyncTask
以String
的形式提供响应,如果这足够的话。您应该查看AsyncTask
上的文档:
https://developer.android.com/reference/android/os/AsyncTask.html
答案 3 :(得分:0)
您将AsyncTask
包装在另一个POJO类中;这样做并不会造成伤害,但收效甚微。
考虑到任务完成后,您将需要某处的回调通知。您的MainClass
将在processDone()
中收到回调,但有些内容需要收听MainClass
才能收到该通知。
这是我一直用于AsyncTask
子类的模式:
public class GetDataRemoteTask extends AsyncTask<String, Void, Data> {
private static final String TAG = "GetDataRemoteTask ";
private WeakReference<GetDataResultListener> mListenerRef;
private Exception mExc;
@Override
protected Data doInBackground(String... params) {
Data result = null;
try {
result = mService.getData(params[0], params[1], params[2]);
} catch (Exception e) {
Log.e(TAG, "Error occurred getting data", e);
mExc = e;
}
return result;
}
@Override
protected void onPostExecute(Data result) {
if (mListenerRef != null) {
GetDataResultListener listener = mListenerRef.get();
if (listener != null) {
if (mExc == null) {
listener.dataReceived(result);
} else {
listener.dataException(mExc);
}
}
}
}
public void setGetDataResultListener(GetDataResultListener listener) {
if (listener == null) {
this.mListenerRef = null;
} else {
this.mListenerRef = new WeakReference<GetDataResultListener >(listener);
}
}
public static interface GetDataResultListener {
public void dataReceived(Data data);
public void dataException(Exception exc);
}
}
首先,在这里,我有一个界面,就像你一样,用于连接AsyncTask
。但是我没有用我的AsyncTask
包含一个实现,我希望我会有Activity
或Fragment
来实现这个接口。 (这就是我使用WeakReference
的原因;如果Activity
完成,我的AsyncTask
不会继续保持Activity
。但这也是意味着我不能使用匿名类监听器,除非客户端持有它的引用。)
我的客户端代码如下所示:
GetDataRemoteTask task = new GetDataRemoteTask();
task.setListener(this);
task.execute(param1, param2, param3);
我还可以找出后台任务中是否发生异常。应始终向客户端报告任何后台异常,这可以决定如何最好地处理异常 - 例如弹出用户对话框,以便他们知道请求失败。
我认为AsyncTask
的一大缺点是它没有更多的结构来处理后台线程中发生的异常。
我的任务包含对异常的引用,但我还使用Pair<Data, Exception>
作为返回结果的类型参数,因此我不需要异常属性。
使用此模式帮助我避免了编码AsyncTask
子类时出现的一些典型问题。