2014-06-30 56 views
0

我發展,因爲解析RSS提要的簡單應用,越來越NetworkOnMainThreadException錯誤,我不得不寫使用異步我的代碼:安卓:RuntimeException的在使用異步

protected List<RSSItem> data; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     GetDataRSS getDataRSS = new GetDataRSS(); 
     getDataRSS.execute(); 

     ArrayAdapter<RSSItem> adapter = new ArrayAdapter<RSSItem>(this, android.R.layout.simple_list_item_1, data); 
     setListAdapter(adapter); 


} 



private class GetDataRSS extends AsyncTask<Object, Void, List<RSSItem>>{ 

    @Override 
    protected List<RSSItem> doInBackground(Object... params) { 
      RSSPullParser parser = new RSSPullParser(); 
      List<RSSItem> items = parser.parseXML(); 
      return items; 
    } 
    @Override 
    protected void onPostExecute(List<RSSItem> result) { 
      data = result; 

    } 
} 

但是,運行我的程序後,我發現了以下錯誤:

06-30 07:35:45.777: E/AndroidRuntime(25093): FATAL EXCEPTION: main 
06-30 07:35:45.777: E/AndroidRuntime(25093): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.parsingrss/com.example.parsingrss.MainActivity}: java.lang.NullPointerException 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2071) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2096) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.app.ActivityThread.access$600(ActivityThread.java:138) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1207) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.os.Handler.dispatchMessage(Handler.java:99) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.os.Looper.loop(Looper.java:213) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.app.ActivityThread.main(ActivityThread.java:4787) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at java.lang.reflect.Method.invokeNative(Native Method) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at java.lang.reflect.Method.invoke(Method.java:511) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at dalvik.system.NativeStart.main(Native Method) 
06-30 07:35:45.777: E/AndroidRuntime(25093): Caused by: java.lang.NullPointerException 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.widget.ListView.setAdapter(ListView.java:465) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.app.ListActivity.setListAdapter(ListActivity.java:265) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at com.example.parsingrss.MainActivity.onCreate(MainActivity.java:26) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.app.Activity.performCreate(Activity.java:5008) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) 
06-30 07:35:45.777: E/AndroidRuntime(25093): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2035) 
06-30 07:35:45.777: E/AndroidRuntime(25093): ... 11 more 

很長一段時間的調試後,終於被我解決我的問題是這樣的:

@Override 
protected void onPostExecute(List<RSSItem> result) { 
    data = result; 
    ArrayAdapter<RSSItem> adapter = new ArrayAdapter<RSSItem>(MainActivity.this, android.R.layout.simple_list_item_1, data); 
    setListAdapter(adapter); 

} 

當我在onCreate方法中使用它時,它似乎是空的。但我的問題是,爲什麼我不能在UI線程(MainActivity)內使用data變量?
在此先感謝。

回答

2

事實上的AsyncTask運行在不同的線程中,這樣的AsyncTask線程和主線程同時放跑。

因此,在完成從網絡獲取數據之前,您的Adapter類已被調用,並且此時數據變量中沒有任何數據。所以發生NullPointerException。

並且您的以下解決方案正在工作,因爲onPostExecute在獲取數據後被調用。

@Override 
protected void onPostExecute(List<RSSItem> result) { 
    data = result; 
    ArrayAdapter<RSSItem> adapter = new ArrayAdapter<RSSItem>(MainActivity.this, android.R.layout.simple_list_item_1, data); 
    setListAdapter(adapter); 

} 
0

您可以。但是當你第一次嘗試使用它時,它不會被初始化,所以你有一個錯誤。初始化爲空列表,你應該沒問題。

+0

我初始化'data'這樣說:'保護名單數據=新的ArrayList ();',錯誤消失,但仍然不能正常工作。 –

+0

這是因爲AsyncTask是異步的,它運行在不同的線程上。如果你寫'ArrayAdapter adapter = new ArrayAdapter (this,android.R.layout.simple_list_item_1,data); setListAdapter(adapter);'在UI線程中它會立即執行(它不會等待來自AsyncTask的響應)。同時AsyncTask將在不同的線程中運行。 – Aniruddha

0

您需要使用Asyantask或線程mechenis進行此類網絡調用。

這裏是網絡運行的非常簡單的例子

class NetworkOperation extends AsyncTask<Void, Integer, String> 
{ 

    public NetworkOperation(){ 

     // Public constructor 
    } 


    protected void onPreExecute(){ 

     // before request created 
     Log.d("PreExceute","On pre Exceute......"); 

    } 

    protected String doInBackground(Void...arg0) { 

     // do your network operation here. 

     Log.d("DoINBackGround","On doInBackground..."); 

     return "You are at PostExecute"; 
    } 


    protected void onPostExecute(String result) { 

     // After network completed, you will getresult here. 
     Log.d(""+result); 

    } 
} 
+0

在AsycTask中給出一個公共構造函數。 –