我正在开发一个解析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
变量?
提前致谢。
答案 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);
}
}