1

我得到了以下問題,希望有人能給我一個提示。android:在MainActivity的AsyncTask中使用arrayadapter <自定義對象>

我有執行一的AsyncTask <字符串,空隙的ArrayList <自定義對象>>的活性。 在doInBackground函數中,我設置了一個新的自定義對象的ArrayList,它也是返回值。 ! 在該ArrayList的是在新創建的ArrayAdapter,它也被設置爲一個ListView(與lv.setAdapter(適配器)使用的onPostExecute方法 到目前爲止好

現在的事情是:在MainActivity回我將再次需要該適配器,因爲我想通過調用adapter.add(items)來添加新的項目。 現在我有AsyncTask作爲我的MainActivity的內部類,並且可以使用相同的listview &相同的arrayadapter

但由於我有另一個需要執行AsyncTask的類,我將該內部類AsyncTask更改爲獨立的.java文件(CustomAsyncTask.java)

- >現在當我嘗試向ArrayAdapter添加新項目時,它會引發NullPointerException! 當然,這就是說,導致ArrayAdapter屬於AsyncTask並且在那裏創建 所以我試圖從MainActivity中提供ListView和ArrayAdapter作爲CustomAsyncTask構造函數的參數,以便在 中使用它,但那不起作用, MainActivity中的ArrayAdapter始終爲空導致異常

任何想法如何解決? 我真的很感激它。

這裏MainActivity.java的代碼:

// global variables 
ArrayAdapter<Custom object> arrayadapter; 
ListView listview; 
ProgressBar progressbar; 

... 

protected void myMethod() { 
    CustomAsyncTask hTask = new CustomAsyncTask(this, listview, progressbar, arrayadapter); 
    hTaskPlaylist.execute(String sth); 
} 

... 

protected void anotherMethod() { 
    arrayadapter.add(item); 
} 

和CustomAsyncTask.java的代碼: 包com.mypackage.test;

import java.util.ArrayList; 

import android.content.Context; 
import android.os.AsyncTask; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.ProgressBar; 

public class CustomAsyncTask extends AsyncTask<String, Void, ArrayList<Custom object>>{ 

    Context context; 
    ListView listview; 
    ProgressBar progressbar; 
    ArrayAdapter<Custom object> arrayadapter; 

    public CustomAsyncTask(Context con, ListView lv, ProgressBar pb, ArrayAdapter<Custom object> aa) { 
     this.context = con; 
     this.listview = lv; 
     this.progressbar = pb; 
     this.arrayadapter = aa; 
    } 

    @Override 
    protected void onPreExecute() { 
     listview.setVisibility(ListView.GONE); 
     progressbar.setVisibility(ProgressBar.VISIBLE); 
     super.onPreExecute(); 
    } 

    @Override 
    protected ArrayList<Custom object> doInBackground(String... params) { 
      ArrayList<Custom object> list = new ArrayList<Custom object>(); 

      ... doing something and populating list 
      return list; 
    } 

    @Override 
    protected void onPostExecute(ArrayList<Custom object> list) { 
     super.onPostExecute(list); 

     arrayadapter = new ArrayAdapter<Custom object>(context, android.R.layout.simple_list_item_1, list); 
     listview.setAdapter(arrayadapter); 

     progressbar.setVisibility(ProgressBar.GONE); 
       listview.setVisibility(ListView.VISIBLE); 
    } 

    } 
} 

回答

1

你可以讓你的ArrayAdapter靜態的。然後每當您要訪問它,你可以簡單地說CustomAsyncTask.arrayadapter.add(項目);您也可以將自己的函數添加到您的自定義asynctask類。你可以創建一些像public ArrayAdapter <> getAdapter()。但要小心,不管怎麼說,你將有多個線程訪問/更改該對象,因此同步訪問將是一個好主意。

你可以嘗試這樣的事情......

ArrayAdapter globalAdapter; 
globalAdapter = new CustomAsyncTask().execute(/*your parameters here*/).get(); 
+0

謝謝..但沒有一種方法可以將值返回給MainActivity(不只是在onPostExecute())? - >'因爲它在AsyncTask是MainActivity的內部類時起作用,不知何故它應該如果它也是一個外部類,那該不該工作呢? – user1515520 2012-07-10 19:55:55

+0

適配器最初是主要活動中的變量嗎?因爲內部類可以訪問外部類的實例變量......是的,它應該可以讓異步任務返回一個數組適配器;但是,對該返回值所做的任何更改都不會保留其他實例。 – Joel 2012-07-10 20:03:18

+0

ArrayAdapter arrayadapter在MainActivity中全局定義(所以當Activity啓動適配器時爲null),然後創建一個新的AsyncTask對象,並將arrayadapter&listview作爲參數並執行它。我在CustomAsyncTask中使用arrayadapter填充listview,填充了一個數組列表。 (在onPostExecute()) 也來自MainActivity的listview被正確設置,只有當我嘗試調用arrayadapter.add(item)時,它會拋出一個NullPointerException – user1515520 2012-07-10 21:19:09

0

現在我想,並通過MainActivity作爲參數,而不是Context, 這裏是我變了:

public class CustomAsyncTask extends AsyncTask<String, Void, ArrayList<Custom object>>{ 

    **MainActivity activity**; 
    ListView listview; 
    ProgressBar progressbar; 
    ArrayAdapter<Custom object> arrayadapter; 

    public CustomAsyncTask(**MainActivity act**, ListView lv, ProgressBar pb, ArrayAdapter<Custom object> aa) { 
     **this.activity = act;** 
     this.listview = lv; 
     this.progressbar = pb; 
     this.arrayadapter = aa; 
    } 

    ... 

    @Override 
    protected void onPostExecute(ArrayList<Custom object> list) { 
     super.onPostExecute(list); 

     arrayadapter = new ArrayAdapter<Custom object>(context, android.R.layout.simple_list_item_1, list); 
     listview.setAdapter(arrayadapter); 
     **activity.arrayadapter = arrayadapter;** 

     progressbar.setVisibility(ProgressBar.GONE); 
     listview.setVisibility(ListView.VISIBLE); 
    } 

} 

是的,它的工作! 謝謝Joel, 但我仍然想知道爲什麼我可以從MainActivity通過listview,在AsyncTask上調用該列表視圖中的函數,並且通常使用該列表視圖回到MainActivity,有什麼想法?

而另一個問題:是不是,在傳遞一個Activity對象,而不是一個Context對象的唯一區別,就是你有機會獲得可用的變量和方法您在Activity界定?

+0

不客氣!當您將ListView傳遞給AsyncTask時,該任務會得到您活動中的listview副本。所以它可以用listview做任何事情,它不會改變你的活動。是的,這基本上就是這樣。有了上下文,你永遠不會知道什麼樣的對象是一個表示。如果你願意,你可以通過執行'MainActivity activity =(MainActivity)context'來將一個上下文作爲你的活動的一個實例。然後您可以完全訪問MainActivity類中的任何函數! – Joel 2012-07-11 19:04:49

+0

但是,如果您嘗試並投射不屬於您的活動實例的上下文,它會拋出空指針異常。 – Joel 2012-07-11 19:06:43

+0

在你說了什麼之後,我是否認爲上下文通常是多餘的或者我錯過了什麼? – user1515520 2012-07-11 21:18:56

相關問題