android:使用异步时的RuntimeException

时间:2014-06-30 03:17:12

标签: android android-asynctask nullpointerexception

我正在开发一个解析RSS提要的简单应用程序,因为收到NetworkOnMainThreadException错误,我不得不使用Async编写代码:

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方法中使用它时,它似乎是null。但我的问题是,为什么我不能在UI线程(MainActivity)中使用data变量?
提前致谢。

3 个答案:

答案 0 :(得分: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);

}

答案 1 :(得分:0)

你可以。但是当你第一次尝试使用它时,它没有被初始化,所以你有一个错误。将它初始化为空列表,你应该没问题。

答案 2 :(得分: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);

    }
}