老师我不太理解为什么在OnCreate()中设置适配器出现空指针异常,而在AsyncTask中会成功

来源:2-4 加载数据到ListView

雎山月

2019-09-07 13:51:16

public class RequestDataActivity extends AppCompatActivity {
    private static final String TAG = "RequestDataActivity";
    private ListView mListView;
    private static LessonResult mLessonResult;

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

        mListView = findViewById(R.id.main_list_view);


        RequestDataAsyncTask dataAsyncTask = new RequestDataAsyncTask(this,this);
        dataAsyncTask.execute();


//        Log.i(TAG, "onCreate: "+mLessonResult.getDataList());
        
        mListView.setAdapter(new RequestDataAdapter(mLessonResult.getDataList(),this));

    }


    public  static class  RequestDataAsyncTask extends AsyncTask<Void,Void,String>{
        public static final String REQUEST_DATA_URL = "http://www.imooc.com/api/teacher?type=2&page=1";
        private WeakReference<RequestDataActivity> mWeakReference;
        private RequestDataActivity mActivity;
        private Context mContext;

        public RequestDataAsyncTask(RequestDataActivity activity, Context context) {
            mWeakReference = new WeakReference<>(activity);
            mContext = context;
        }

        public static final int REQUEST_TIMEOUT = 5000;
        public static final String STATUS = "status";
        public static final String MSG = "msg";
        public static final String DATA = "data";
        public static final String ID = "id";
        public static final String DESCRIPTION = "description";
        public static final String NAME = "name";
        public static final String LEARNER = "learner";
        public static final String PIC_BIG = "picBig";
        public static final String PIC_SMALL = "picSmall";

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //loading
            mActivity = mWeakReference.get();
        }

        @Override
        protected String doInBackground(Void... voids) {
            String result = request(REQUEST_DATA_URL);
            Log.i(TAG, "doInBackground: "+result);
            return result;
        }

        private String request(String urlString) {
            try {
                URL url = new URL(urlString);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                connection.setConnectTimeout(REQUEST_TIMEOUT);
                connection.setRequestMethod("GET");
                connection.connect();

                int responseCode = connection.getResponseCode();

                if (responseCode == HttpURLConnection.HTTP_OK){
                    InputStreamReader inputStreamReader = new InputStreamReader(connection.getInputStream());
                    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                    StringBuilder stringBuilder = new StringBuilder();

                    String line;

                    while((line = bufferedReader.readLine())!=null){
                        stringBuilder.append(line);
                    }
                    inputStreamReader.close();
                    bufferedReader.close();
                    String result = stringBuilder.toString();
                    return result;
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            // loading 消失,数据处理 刷新界面

            mLessonResult = new LessonResult();
            List<Lesson> lessonList = new ArrayList<>();


            try {
                JSONObject jsonObject = new JSONObject(s);
                int status = jsonObject.getInt(STATUS);
                mLessonResult.setStatus(status);
                String message = jsonObject.getString(MSG);
                mLessonResult.setMessage(message);
                JSONArray jsonArray = jsonObject.getJSONArray(DATA);
                for (int index = 0; index < jsonArray.length(); index++) {
                    Lesson lesson = new Lesson();
                    JSONObject itemJSONObject = (JSONObject) jsonArray.get(index);
                    lesson.setId(itemJSONObject.getInt(ID));
//                    lesson.setDescription(itemJSONObject.getString(DESCRIPTION));
                    lesson.setName(itemJSONObject.getString(NAME));
//                    lesson.setLearner(itemJSONObject.getInt(LEARNER));
//                    lesson.setPicBig(itemJSONObject.getString(PIC_BIG));
//                    lesson.setPicSmall(itemJSONObject.getString(PIC_SMALL));

                    lessonList.add(lesson);

                }
                mLessonResult.setDataList(lessonList);

            } catch (JSONException e) {
                e.printStackTrace();
            }
            mActivity.mListView.setAdapter(new RequestDataAdapter(mLessonResult.getDataList(),mContext));
        }
    }
}

老师,是不是ui线程和AsyncTask开启的线程同时进行,ui线程率先跑完,跑到获取集合数据的时候,AsyncTask开启的线程还没跑完,所以没有为集合进行赋值操作,故而产生了空指针异常?

写回答

1回答

好帮手慕雪

2019-09-08

因为你需要去网上取数据,这需要一个过程,而你全在onCreate()中,设置适配器时,无法保证数据已经下载完毕了。如果没有下载完就会出现异常。而如果是在AsyncTask中,是异步任务,让数据下载完再去设置适配器,这样适配器中的数据就不会为空了。祝:学习愉快

0

0 学习 · 1800 问题

查看课程