我正在尝试在后台进程中发布两种不同类型的进度。我试图有时发布一个字符串,有时发布一个整数。我也通过重载来处理 onProgressUpdate 中的两种参数。但是,当我声明 AsyncTask 类时,我有参数,这就是为什么它期望我仅发送字符串类型参数。有没有办法处理这两种类型的publishProgress事件?
最佳答案
基本上有两种方法可以解决您的问题:
第一个非常简单,您只需 publishUpdate(String)
即可,然后在 onProgressUpdate(String)
中检查字符串是 int 还是 a字符串,并以不同的方式处理每种情况,如下所示:
private class MyAsyncTask extends AsyncTask<Void, String, Void> {
//Executed on main UI thread.
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
try{
Integer i = Integer.parseInt(values[0]);
TextView v1 = (TextView) findViewById(R.id.textView1);
v1.setText(String.valueOf(i));
}
catch(NumberFormatException e){
TextView v2 = (TextView) findViewById(R.id.textView3);
v2.setText(values[0]);
}
}
@Override
protected Void doInBackground(Void... params) {
int i = 0;
while(i < 100){
try {
if(i%2 == 0){
publishProgress("Divisible by 2: " + String.valueOf(i));
}
publishProgress(String.valueOf(i));
i++;
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
}
在上面的示例中,我只是尝试将字符串解析为 Integer
- 如果它有效,那么我 100% 确定它是一个 int - 如果它抛出异常,那么它就是一个 字符串
。
但是,如果您想要更多控制,则需要实现您自己的 AsyncTask 版本,该版本支持一个或多个进度更新。实现此目的的唯一方法是直接使用 Handlers
( http://developer.android.com/reference/android/os/Handler.html ) 和 Thread
( http://developer.android.com/reference/java/lang/Thread.html )(最好包装在类似于 AsyncTask 的更具逻辑性的类中) :
import android.os.Handler;
import android.os.Looper;
public abstract class DIYAsyncTask<Params, IntProgress, StringProgress, Result> {
private Result backGroundResult;
//Run on UI thread
@SuppressWarnings("unchecked")
protected void execute(Params... params){
final Params[] thisParams = params;
Thread worker = new Thread(){
public void run(){
prepareForPreExecute();
backGroundResult = doInBackground(thisParams);
prepareForPostExecute();
}
};
worker.setPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
worker.start();
}
//Code to start onPreExecute on UI thread
private void prepareForPreExecute(){
Handler ui_handler = new Handler(Looper.getMainLooper());
ui_handler.post(
new Runnable(){
public void run(){
onPreExecute();
}
}
);
}
//Code to start onPostExecute on UI thread
private void prepareForPostExecute(){
Handler ui_handler = new Handler(Looper.getMainLooper());
ui_handler.post(
new Runnable(){
public void run(){
onPostExecute(backGroundResult);
}
}
);
}
//Always run on worker thread
@SuppressWarnings("unchecked")
protected abstract Result doInBackground(Params... params);
//Always run on UI
protected void onPreExecute(){
}
//Always run on UI
protected void onPostExecute(Result result){
}
//Run on worker
@SuppressWarnings("unchecked")
protected void publishIntProgress(IntProgress... values){
Handler ui_handler = new Handler(Looper.getMainLooper());
final IntProgress[] thisProgress = values;
ui_handler.post(
new Runnable(){
@Override
public void run(){
onIntProgressUpdate(thisProgress);
}
}
);
}
//Always run on UI
@SuppressWarnings("unchecked")
protected void onIntProgressUpdate(IntProgress... values){
}
//Run on worker
@SuppressWarnings("unchecked")
protected void publishStringProgress(StringProgress... values){
Handler ui_handler = new Handler(Looper.getMainLooper());
final StringProgress[] thisProgress = values;
ui_handler.post(
new Runnable(){
@Override
public void run(){
onStringProgressUpdate(thisProgress);
}
}
);
}
//Always run on UI
@SuppressWarnings("unchecked")
protected void onStringProgressUpdate(StringProgress... values){
}
}
然后您可以像这样覆盖它(注意与仅使用 AsyncTask 的相似之处)
private class MyDIYAsyncTask extends DIYAsyncTask<Void, Integer, String, Void> {
//Executed on main UI thread.
@Override
protected void onIntProgressUpdate(Integer... values) {
super.onIntProgressUpdate(values);
TextView v = (TextView) findViewById(R.id.textView1);
v.setText(String.valueOf(values[0]));
}
@Override
protected void onStringProgressUpdate(String... values) {
super.onStringProgressUpdate(values);
TextView v = (TextView) findViewById(R.id.textView3);
v.setText(values[0]);
}
@Override
protected Void doInBackground(Void... params) {
int i = 0;
while(i < 100){
try {
publishIntProgress(i);
publishStringProgress("MyString" + String.valueOf(i));
i++;
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
}
关于android - 可以在AsyncTask中重载publishProgress吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23251315/