我想在後臺進程中發佈兩種不同的進度。我試圖在某個時間發佈一個字符串,而另一次發佈一個整數。我在onProgressUpdate中通過重載它們來處理兩種參數。但是當我聲明我的AsyncTask類時,我有這樣的理由,那就是爲什麼它期望我只發送字符串類型參數。有沒有辦法處理這兩種類型的publishProgress事件?可以發佈進程在AsyncTask中重載嗎?
2
A
回答
3
基本上有解決你的問題,有兩種方式:
第一個是非常簡單的,你只是一直publishUpdate(String)
,然後在你的onProgressUpdate(String)
檢查字符串是否是一個int或字符串,並處理每情況不同,像這樣:
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 - 如果它拋出一個異常,那麼它是一個String
。
但是,如果您想要更多控制,則需要實現您自己的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;
}
}
相關問題
- 1. Android - AsyncTask,都是進度發佈的電話發佈嗎?
- 2. 在Android ViewModel中使用AsyncTask可以嗎?
- 3. AsyncTask可以啓動另一個AsyncTask嗎?
- 4. 在VHDL中可重入進程嗎?
- 5. Android:在AsyncTask中發佈JSON
- 6. AsyncTaskLoader可以取代AsyncTask嗎?
- 7. 可以在python內部發布嗎?
- 8. 應用程序swf可以在AIR中重新加載嗎?
- 9. 守護進程可以在python中fork子進程嗎?
- 10. Android AsyncTask奇怪地發佈重複
- 11. 我可以在工作流程中觸發Youtrack的版本發佈嗎?
- 12. 我可以以編程方式發佈狀態評論嗎?
- 13. 我可以加載多個COMCTL32.dll到一個進程中嗎?
- 14. 無法編譯發佈,可以進行調試嗎? [iphone]
- 15. 我可以重新加載Mono CSharpRepl中的程序集嗎?
- 16. mergExt - mergPopActivity也可以發佈電影嗎?
- 17. 你可以發佈到PUT signedUrl嗎?
- 18. 我可以發佈msi和exe嗎?
- 19. Google+ API可以發佈信息嗎?
- 20. 我可以使用NPM發佈和使用二進制.NET程序集嗎?
- 21. 我可以重載十進制類型的+運算符嗎?
- 22. 我可以用光標加載器代替asynctask嗎?
- 23. 在AsyncTask中下載進度android
- 24. 在Android的Realm中可以進行內部進程通信嗎?
- 25. 在rails中可以動態加載類佈局嗎?
- 26. Java的FutureTask可以替代AsyncTask嗎?
- 27. doInBackground運行時可以停止asynctask嗎?
- 28. 兩個進程可以渲染到一個OpenGL畫布嗎?
- 29. AsyncTask進程
- 30. 重新發布App Store應用程序可行嗎?
沒有辦法使用標準的AsyncTask做到這一點 - 你要麼必須使用一個類型,這兩種類型都符合,或實現自己的AsyncTask。 – Dyrborg
我在我的嵌套AsyncTask類的活動中實現了SensorEventListener類。我不能只是創建一個字符串全局變量,並更新AsyncTask中的變量,並且onSensorChanged()方法會選取變量並將其設置爲文本?我完全可以避免postProgress()方法嗎? –
如果我正確理解你,那將是一個非常糟糕的設計策略。創建自己的AsyncTask實現將會更好,它支持多種更新方法,因此您不僅限於1種方法。或者,您可以在publishUpdate()方法中始終使用字符串,然後在onProgressUpdate()中檢查字符串是否爲整數(使用Integer.parseInt(您的字符串)),並相應地執行操作。 – Dyrborg