老师我不太理解为什么在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回答
因为你需要去网上取数据,这需要一个过程,而你全在onCreate()中,设置适配器时,无法保证数据已经下载完毕了。如果没有下载完就会出现异常。而如果是在AsyncTask中,是异步任务,让数据下载完再去设置适配器,这样适配器中的数据就不会为空了。祝:学习愉快
相似问题