Android:使用 Asynctask 时 Recyclerview 出现问题
Posted
技术标签:
【中文标题】Android:使用 Asynctask 时 Recyclerview 出现问题【英文标题】:Android: problem with Recyclerview when using Asynctask 【发布时间】:2020-02-02 23:55:50 【问题描述】:我可以在 Asynctask 中使用 Json 从 API 获取数据,但问题是当我使用 Recyclerview 时。我得到空指针异常错误。请问谁能帮帮我?
***MainActivity.java***
private List<Certifications> mCertifications = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.certificationRecyclerview);
new fetchData().execute();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new GreenAdapter(mCertifications);
recyclerView.setAdapter(mAdapter);
***GreenAdapter.java***
public class GreenAdapter extends RecycrView.Adapter<GreenAdapter.ViewHolder>
private Context mContext;
private List<Certifications> mCertifications;
public GreenAdapter(List<Certifications> certifications)
this.mCertifications = certifications;
/** Inner class */
// Stores and recycles views as they are scrolled off screen
public static class ViewHolder extends RecyclerView.ViewHolder
private TextView certificationTextview;
private TextView meaningTextview;
private TextView orderTextview;
public ViewHolder(@NonNull View itemView)
super(itemView);
certificationTextview = (TextView) itemView.findViewById(R.id.certificationInfo);
meaningTextview= (TextView) itemView.findViewById(R.id.meaning);
orderTextview = (TextView) itemView.findViewById(R.id.order);
// Methods
// Usually involves inflating a layout from XML and returning the holder
//Create New Views
@NonNull
@Override
public GreenAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View certificationView = inflater.inflate(R.layout.certification_list,
parent, false);
//Return a new holder instance
final ViewHolder certificationViewHolder = new ViewHolder(certificationView);
return certificationViewHolder;
//binds the data to the Textview in each row
// Involves populatind data into the item through holder
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
// get the data model based on position
Certifications certific = mCertifications.get(position);
//set itemviews based on your views and data model
holder.certificationTextview.setText(certific.getCertification());
holder.meaningTextview.setText(certific.getMeaning());
holder.orderTextview.setText(certific.getOrder());
@Override
public int getItemCount()
return mCertifications.size();
**I copied the following from other post**
public void clear()
mCertifications.clear();
notifyDataSetChanged();
public void addAll(List<Certifications> list)
mCertifications.addAll(list);
notifyDataSetChanged();
***Certifications.java***
public class Certifications
private String mCertification;
private String mMeaning;
private int mOrder;
public Certifications(String certification,String meaning, int order)
mCertification = certification;
mMeaning = meaning;
mOrder = order;
public String getCertification()
return mCertification;
public String getMeaning()
return mMeaning;
public int getOrder()
return mOrder;
***FetchData.java***
Public class fetchData extends AsyncTask<String,Void, List<Certifications>>
private GreenAdapter mGreenAdapter;
// Create an empty ArrayList that we can start adding Certifications to
List<Certifications> mCertifications = new ArrayList<>();;
protected List<Certifications> doInBackground(String... voids)
try
URL url = new URL("API");
HttpsURLConnection httpsURLConnection= (HttpsURLConnection) url.openConnection();
InputStream inputStream=httpsURLConnection.getInputStream();
BufferedReader bufferedReader= new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while (line!=null)
line = bufferedReader.readLine();
data = data + line;
// Create a JASONObject from the JSON_RESPONSE string
JSONObject root = new JSONObject(data);
JSONObject jsonObject = root.getJSONObject("certifications");
//提取与名为“US”的键关联的JSONArray //代表美国认证列表
JSONArray jsonArray= jsonObject.getJSONArray("US");
for (int i=0; i<jsonArray.length();i++)
JSONObject jasonObject=(JSONObject) jsonArray.get(i);
String cert = jasonObject.getString("certification");
String meaning =jasonObject.getString("meaning");
int order = jasonObject.getInt("order");
Certifications certification = new Certifications(cert, meaning, order);
mCertifications.add(certification);
**Catch code here**
return mCertifications; **Data**
@Override
protected void onPostExecute(final List<Certifications> dataParsed)
//运行调试时以下代码出现空指针异常
// 第一次尝试。结果:NullPointerException
mGreenAdapter.clear();
mGreenAdapter.addAll(dataParsed);
// 第二次尝试。结果:NullPointerException
mGreenAdapter = new GreenAdapter( dataParsed);
mRecyclerView.setAdapter(mGreenAdapter);
// onPostExecute parenthesis
// fetchData.java
【问题讨论】:
你可能想看看使用 Retrofit 而不是 AsyncTask 来处理 http 请求和解析 Json 现在我必须使用 AsyncTask,然后我会切换到 Retrofit 【参考方案1】:打电话
new fetchData().execute();
设置适配器后。你的 onCreate 方法看起来像
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.certificationRecyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new GreenAdapter(mCertifications);
recyclerView.setAdapter(mAdapter);
new fetchData().execute();
【讨论】:
我尝试了您的代码,但仍然无法正常工作。我还尝试使用硬编码数据而不是 HTTP 请求,但我只能看到一行数据。【参考方案2】:问题是在使用 JSON 获取 Asynctask 中的数据时,我无法将数据填充到 RecyclerView。 如果我为 AsyncTask 创建一个新类,我必须在 MainAcitivity.java 中声明 AsyncTask,否则为 NullPointerException。 我在适配器类中声明了一个方法
public void setData(List<Certifications> data)
//List<Certifications> mCertification;
mCertifications = data;
notifyDataSetChanged();
我也关注 Viswanath Kumar Sandu 的帖子,这是我的 MainActivity.java
public class MainActivity extends AppCompatActivity
private RecyclerView recyclerView;
private GreenAdapter mGreenAdapter;
private List<Certifications> mCertifications = new ArrayList<>();;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.certificationRecyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
mGreenAdapter = new GreenAdapter();
recyclerView.setAdapter(mGreenAdapter);
new fetchData().execute();
public class fetchData extends AsyncTask<String,Void, List<Certifications>>
String data = "";
String dataParsed = "";
String singlePass = "";
protected List<Certifications> doInBackground(String... voids)
try
URL url = new URL("https: api);
HttpsURLConnection httpsURLConnection = (HttpsURLConnection)
url.openConnection();
InputStream inputStream = httpsURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(inputStream));
String line = "";
while (line != null)
line = bufferedReader.readLine();
data = data + line;
JSONObject root = new JSONObject(data);
JSONObject jsonObject = root.getJSONObject("certifications");
JSONArray jsonArray = jsonObject.getJSONArray("US");
for (int i = 0; i < jsonArray.length(); i++)
JSONObject jasonObject = (JSONObject) jsonArray.get(i);
String cert = jasonObject.getString("certification");
String meaning = jasonObject.getString("meaning");
int order = jasonObject.getInt("order");
Certifications certification = new Certifications(cert, meaning, order);
mCertifications.add(certification);
jsonArray = jsonObject.getJSONArray("CA");
for (int i = 0; i < jsonArray.length(); i++)
JSONObject jasonObject = (JSONObject) jsonArray.get(i);
String cert = jasonObject.getString("certification");
String meaning = jasonObject.getString("meaning");
int order = jasonObject.getInt("order");
Certifications certification = new Certifications(cert, meaning,order);
mCertifications.add(certification);
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (JSONException e)
e.printStackTrace();
return mCertifications;
@Override
protected void onPostExecute(final List<Certifications> dataParsed)
mGreenAdapter.setData(dataParsed);
//onPostExecute
// AsyncTask
//MainActivity
【讨论】:
以上是关于Android:使用 Asynctask 时 Recyclerview 出现问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 中进行后台工作时使用 AsyncTask 显示 ProgressDialog? [复制]
Android - 传递按钮实例时避免 AsyncTask 中的内存泄漏
在 IntentService 和 AsyncTask (Android) 之间使用共享代码时,领域“从不正确的线程访问”错误