java - 为什么我的字符串没有在 AsyncTask 中填充?
问题描述
我的字符串(这是字符串:headings[]、descs[]、url[]、urlToImg[])在我使用它们后被初始化,这导致了 nullPointerException!如何实现字符串初始化,以便我的字符串可以动态初始化?
在这里,我在 parseResult() 方法的帮助下初始化字符串运行时,该方法由扩展 AsyncTask 类的类调用。passrseResult() 方法正在初始化字符串!但与此同时,在创建“NewsAdapter”对象时,主线程在 onCreate() 方法中使用了字符串,因此字符串为空,导致 nullPointerException!
package com.example.pritam.medoc;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Objects;
public class FragmentNews extends Fragment {
String newsAPIUrl;
ListView newsList;
String headings[];
String descs[];
String url[];
String urlToImg[];
//strore url for images in string[]
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
newsAPIUrl ="Some APIKey that i have";
new AsyncHTTPTask().execute(newsAPIUrl);
View v=inflater.inflate(R.layout.fragment_news,container,false);
newsList=v.findViewById(R.id.listview_news);
NewsAdapter newsAdapter=new NewsAdapter(Objects.requireNonNull(getActivity()).getApplicationContext(),headings,descs,url,urlToImg);
newsList.setAdapter(newsAdapter);
/*newsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//this how to acces link from adapter table String a[]=newsAdapter.adp_descs;
//redirect to the news!
}
});*/
return inflater.inflate(R.layout.fragment_news,container,false);
}
class NewsAdapter extends ArrayAdapter<String>
{
Context context;
String adp_headings[];
String adp_descs[];
String adp_url[];
String adp_urlToImg[];
//try to store url for images
NewsAdapter(Context c, String _head[], String _desc[],String _url[], String _urlToImg[])
{
super(c,R.layout.adapter_listview,R.id.news_heading,_head);
this.context=c;
this.adp_headings=_head;
this.adp_descs=_desc;
this.adp_url=_url;
this.adp_urlToImg=_urlToImg;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
LayoutInflater layoutInflater=(LayoutInflater)getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View customListLayout=layoutInflater.inflate(R.layout.adapter_listview,parent,false);
ImageView news_img=customListLayout.findViewById(R.id.news_image);
TextView news_head=customListLayout.findViewById(R.id.news_heading);
TextView news_desc=customListLayout.findViewById(R.id.news_desc);
//here try to populate image from url news_img.setImageResource();
news_head.setText(adp_headings[position]);
news_desc.setText(adp_descs[position]);
return customListLayout;
}
}
public class AsyncHTTPTask extends AsyncTask<String, Void, String>
{
@Override
protected String doInBackground(String... urls) {
String result="";
URL this_url;
HttpURLConnection urlConnection;
try{
this_url=new URL(urls[0]);
urlConnection=(HttpURLConnection)this_url.openConnection();
String response=streamToString(urlConnection.getInputStream());
parseResult(response);
return response;
}
catch (Exception e)
{
Log.i("",e.toString());
}
return null;
}
}
String streamToString(InputStream stream)throws IOException
{
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(stream));
String data;
String result="";
while ((data=bufferedReader.readLine()) != null)
{
result+=data;
}
if(null != stream)
{
stream.close();
}
return result;
}
private void parseResult(String result) throws JSONException {
JSONObject response=new JSONObject(result);
JSONArray articles=response.optJSONArray("articles");
headings=new String[articles.length()];
descs=new String[articles.length()];
url=new String[articles.length()];
urlToImg=new String[articles.length()];
for(int i=0; i<articles.length(); i++)
{
JSONObject article=articles.optJSONObject(i);
headings[i]=article.optString("title");
//Log.i("Title",headings[i]);
descs[i]=article.optString("description");
//Log.i("Description",descs[i]);
url[i]=article.optString("url");
//Log.i("url",url[i]);
urlToImg[i]=article.optString("urlToImage");
//Log.i("urlToImage",urlToImg[i]);
}
}
}
在创建 NewsAdapter 的对象时,我得到了那个错误!
解决方案
您的字符串没有被填充,因为AsyncTask
用于获取数据的代码和用于填充列表的代码并行运行。当您的异步任务完成执行时,该列表已被填充。您需要了解异步任务中编码的任务发生在单独的线程中。
您要做的是在异步任务从 API 获取数据后填充列表。您必须检查如何从异步任务中更新您的列表(您可能想搜索 method runOnUiThread
。我可能对这种方法有误,因为我在 Android 上工作已经很长时间了。但我确信我的方法是正确的) .
您还可以查看以下链接。
推荐阅读
- python - Scikit skimage regionprops 获取连接区域(python)
- python - Python(字符串):使用保存在 DataFrame 单元格中的字符串作为熊猫公式
- sql - COALESCE 类型 jsonb 和 boolean 无法匹配
- kotlin - 在 Kotlin 中使用来自不同上下文的扩展函数
- c# - 如何使用 linq 绑定枚举类
- ios - watchOS 7 中不再更新的并发症
- amazon-web-services - 如何从 shell 脚本确认 aws cloudformation validate-template 命令?
- reactjs - React 组件似乎因为子组件而重新渲染(但不应该)
- laravel - 照亮\数据库\查询异常 | SQLSTATE [42S21]:列已存在:1060 列名重复
- php - 当用户未登录无法看到页面 wordpress 时的功能