2013-03-15 113 views
1

這麼多小時試圖弄清楚這一點,我已經閱讀了很多問題,論壇,答案..但它仍然不會更新用戶界面。AsyncTask更新UI

我的最終目標是從用戶那裏獲取一個搜索詞,然後發送一個httprequest到PHP腳本中,該腳本用JSON回覆。這工作正常,所以我不會深入研究它。

我的問題是在完成後更新UI。我可以得到HTTP結果,但現在,我只是試圖用一個基本的字符串更新UI,然後再實現諸如帶有監聽器的按鈕等所有結果的大變化。現在,只需添加簡單的String到UI。

onPreExecute()將一個字符串添加到用戶界面,並以某種方式正常工作,如下所示。

問題出在onPostExecute ..就像我說的,現在,只是一個字符串,測試(它將是一個列表或最終)。它根本不起作用,總是拋出異常。

public class DisplaySearchActivity extends ListActivity { 

ArrayList<String> listItems=new ArrayList<String>(); 
ArrayAdapter<String> adapter = null; 



private class updateUI extends AsyncTask<String, Void, String>{ 

    @Override 
    protected void onPreExecute() { 
     listItems.add("Retrieving Results..."); 
       // This actually works just like that 
    } 

    @Override 
    protected String doInBackground(String... message) { 
    final List<HashMap<String,String>> blist = httpSearch.search(message[0]); 
    return "It has done"; 
    } 

    @Override 
    protected void onPostExecute(String b){ 
     Log.v("ok", "shane - "+ b); 
     listItems.add("Business: "+ b); 
        adapter.notifyDataSetChanged(); 
    } 
} 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_display_search); 

    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems); 
    setListAdapter(adapter); 

    // final String message = getIntent().getStringExtra("input"); 
    final String message = "third+level"; 

    new updateUI().execute(message); 

} // end onCreate 


} 

這裏是例外

03-15 13:38:41.190: V/ok(15732): shane - It has done 
03-15 13:38:41.190: D/AndroidRuntime(15732): Shutting down VM 
03-15 13:38:41.190: W/dalvikvm(15732): threadid=1: thread exiting with uncaught exception (group=0x4142a2a0) 
03-15 13:38:41.200: E/AndroidRuntime(15732): FATAL EXCEPTION: main 
03-15 13:38:41.200: E/AndroidRuntime(15732): java.lang.NullPointerException 
03-15 13:38:41.200: E/AndroidRuntime(15732): at ie.whereis.DisplaySearchActivity$updateUI.onPostExecute(DisplaySearchActivity.java:34) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at ie.whereis.DisplaySearchActivity$updateUI.onPostExecute(DisplaySearchActivity.java:1) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.AsyncTask.finish(AsyncTask.java:631) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.AsyncTask.access$600(AsyncTask.java:177) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.Handler.dispatchMessage(Handler.java:99) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.Looper.loop(Looper.java:137) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.app.ActivityThread.main(ActivityThread.java:4898) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at java.lang.reflect.Method.invokeNative(Native Method) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at java.lang.reflect.Method.invoke(Method.java:511) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773) 
03-15 13:38:41.200: E/AndroidRuntime(15732): at dalvik.system.NativeStart.main(Native Method) 

我認爲這是由行拋出:

adapter.notifyDataSetChanged(); 

但我就是不真正瞭解適配器做什麼,即使經過很多閱讀。我不知道爲什麼在執行工作:S,但後在一個不是爲什麼

任何幫助非常感謝。


謝謝,我已經評論瞭解決方案。抱歉無法完成投票。的< 15因果報應

+0

我適配器實例化兩次,似乎是這個問題,並在去除最終ArrayAdapter 的建議,這個問題已經解決assing .. 謝謝你漂亮的腦袋有! – shanehoban 2013-03-15 13:55:53

回答

1

在你的onCreate之前更換

final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems); 

adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems); 

除去最後ArrayAdapter

+0

哦,我的上帝,這工作。你介意解釋它爲什麼做?我不太明白。附:我會盡快標記正確.. 編輯:ohhh我有適配器創建兩次!衛生署! – shanehoban 2013-03-15 13:51:23

+1

與最終ArrayAdapter 適配器在你的oncreate你正在創建一個本地變量適配器和適配器實例變量declard在類的開始(你在Asynctask OnpostExecute中使用)保持爲空:) ..是啊,你在編輯:) – baboo 2013-03-15 13:56:23

1

使用

DisplaySearchActivity.this.adapter.notifyDataSetChanged(); 

代替

adapter.notifyDataSetChanged();

onPostExecute方法訪問updateUI類的適配器實例,因爲你已經宣佈adapter=null

0

當你調用adapter.notifyDataSetChanged();的適配器將使用舊的da TA,你需要再經過修改的列表數據調用adapter.notifyDataSetChanged();

1

你是隱藏的實例字段adapteronCreate方法中。

而不是

final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems); 

使用

this.adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems); 
0

所有的Firsty,爲什麼你有你的適配器聲明爲final? 看起來您正試圖在活動不可見時修改視圖。你應該將asynctask實例化成一個成員變量,並在你的Activity的onStop方法中停止它:myAsyncTask.cancel(true);

1

您的適配器爲空。你設置的列表是有界的,直到oncreate()而已。不要在oncreate()中再次定義。只需 adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems);