PostExecute中出现NullPointerException,TextView赋值失败求助
搞定TextView在PostExecute中触发NullPointerException的问题
嘿,我看了你遇到的问题——明明已经确认LIST<ArrayList<HashMap>>不为空,但在onPostExecute里给TextView赋值时还是炸了空指针。结合你贴的代码片段,我猜核心问题出在你的DBResult类继承了MainActivity,这在Android开发里是个典型的误区,咱们一步步拆解解决:
为啥会出问题?
- 首先,Android的Activity实例是系统负责创建和管理的,你手动让
DBResult继承MainActivity,相当于试图自己实例化一个Activity,但这个实例并没有经过系统的初始化流程(比如没调用setContentView加载布局),导致你要找的TextView根本没被初始化,自然是null。 - 另外,如果
DBResult是用来做异步请求的AsyncTask,那继承Activity完全没必要,反而会搞乱上下文,让你拿不到正确的控件引用。
具体解决方案
情况1:DBResult是异步任务(AsyncTask)
把DBResult改成继承AsyncTask,通过构造函数传入TextView的引用(用弱引用避免内存泄漏),这样就能安全地在onPostExecute中操作控件了:
public class DBResult extends AsyncTask<Void, Void, ArrayList<HashMap<String,String>>> { private WeakReference<TextView> mTextViewRef; JSONParser jParser = new JSONParser(); ArrayList<HashMap<String,String>> LIST = new ArrayList<>(); private static String url_dataget = "..."; // 你的接口地址 // 构造函数传入目标TextView public DBResult(TextView targetTextView) { mTextViewRef = new WeakReference<>(targetTextView); } @Override protected ArrayList<HashMap<String,String>> doInBackground(Void... voids) { // 这里写你的网络请求、填充LIST的逻辑 // 比如调用jParser获取数据并存入LIST return LIST; } @Override protected void onPostExecute(ArrayList<HashMap<String,String>> result) { super.onPostExecute(result); TextView textView = mTextViewRef.get(); // 先检查TextView和数据都不为空 if(textView != null && result != null && !result.isEmpty()){ // 把LIST转成要展示的字符串格式 StringBuilder content = new StringBuilder(); for(HashMap<String,String> item : result){ content.append(item.get("你的键名")).append("\n"); // 替换成你实际的键 } textView.setText(content.toString()); } } }
然后在MainActivity里这样调用:
// 比如在onCreate里初始化TextView并启动任务 TextView myTextView = findViewById(R.id.your_textview_id); // 替换成你布局里的TextView id new DBResult(myTextView).execute();
情况2:DBResult是独立的Activity
如果DBResult是一个单独的页面Activity,那必须在onCreate里先加载布局,再初始化TextView:
public class DBResult extends AppCompatActivity { private TextView mDisplayTextView; ArrayList<HashMap<String,String>> LIST = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.db_result_layout); // 加载你的布局文件 mDisplayTextView = findViewById(R.id.your_textview_id); // 初始化TextView // 启动异步任务获取数据 new FetchDataTask().execute(); } // 内部类做异步请求 private class FetchDataTask extends AsyncTask<Void, Void, ArrayList<HashMap<String,String>>> { JSONParser jParser = new JSONParser(); private static String url_dataget = "..."; @Override protected ArrayList<HashMap<String,String>> doInBackground(Void... voids) { // 网络请求填充LIST的逻辑 return LIST; } @Override protected void onPostExecute(ArrayList<HashMap<String,String>> result) { super.onPostExecute(result); if(mDisplayTextView != null && result != null && !result.isEmpty()){ StringBuilder content = new StringBuilder(); for(HashMap<String,String> item : result){ content.append(item.get("你的键名")).append("\n"); } mDisplayTextView.setText(content.toString()); } } } }
最后再检查这几点
- 确认布局里的TextView id和代码里
findViewById的id完全一致,大小写都不能错! - 如果是在Fragment里用,要等
onViewCreated之后再获取TextView,不然也会拿不到。 - 用弱引用持有TextView/上下文,避免Activity销毁后异步任务还持有引用导致内存泄漏和空指针。
内容的提问来源于stack exchange,提问作者ThatOneJavaGuy
相关产品推荐
相关产品推荐

