如果这个有效,请让我知道!请注意,从任何不是从doInBackground调用的方法中调用doProgress几乎肯定会导致错误。
是的,它有效。我扩展了它,以便您不需要将AsyncTask作为参数传递给您的方法。如果(像我一样)您已经编写了所有方法,然后才决定实际上需要发布一些进度,或者在我的情况下,从AsyncTask更新UI,这特别有用:
public abstract class ModifiedAsyncTask<A,B,C> extends AsyncTask<A,B,C>{
private static final HashMap<Thread,ModifiedAsyncTask<?,?,?>> threads
= new HashMap<Thread,ModifiedAsyncTask<?,?,?>>();
@Override
protected C doInBackground(A... params) {
threads.put(Thread.currentThread(), this);
return null;
}
public static <T> void publishProgressCustom(T... t) throws ClassCastException{
ModifiedAsyncTask<?, T, ?> task = null;
try{
task = (ModifiedAsyncTask<?, T, ?>) threads.get(Thread.currentThread());
}catch(ClassCastException e){
throw e;
}
if(task!=null)
task.publishProgress(t);
}
}
public class testThreadsActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void Button1Clicked(View v){
MyThread mthread = new MyThread();
mthread.execute((Void[])null);
}
private class MyThread extends ModifiedAsyncTask<Void, Long, Void>{
@Override
protected Void doInBackground(Void... params) {
super.doInBackground(params);
while(true){
myMethod(System.currentTimeMillis());
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
return null;
}
}
}
protected void onProgressUpdate(Long... progress) {
((TextView) findViewById(R.id.textView2)).setText("The Time is:" + progress[0]);
}
}
private void myMethod(long l){
ModifiedAsyncTask.publishProgressCustom(new Long[]{l});
}
}
听起来对我来说有点不太好,还有其他人有更好的方法吗?
我的方法可能更糟。我调用了一个静态方法doProgress(我称之为publishProgressCustom)。它可以从任何地方调用而不会产生错误(如果线程在hashMap中没有相应的AsyncTask,则不会调用publishProgress)。缺点是您必须在线程启动后自己添加Thread-AsyncTask映射。(很遗憾,您无法覆盖AsyncTask.execute(),因为这是final)。我在超类中重写了doInBackground(),这样任何扩展它的人只需将super.doInBackground()放在自己的doInBackground()的第一行即可。
我不了解线程和AsyncTask的足够知识,不知道HashMap引用在线程和/或AsyncTask结束时会发生什么。我怀疑会发生糟糕的事情,所以我不建议任何人在自己的代码中尝试我的解决方案,除非他们知道得更好。