Android: проблема с Recyclerview при использовании Asynctask - PullRequest
0 голосов
/ 04 октября 2019

Я могу получить данные, используя Json из API в Asynctask, но проблема в том, когда я использую 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");

// Извлечь JSONArray, связанный с ключом под названием "US"// который представляет список сертификатов США

       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

Ответы [ 2 ]

0 голосов
/ 08 октября 2019

Проблема заключалась в том, что я не мог заполнить данные в RecyclerView при использовании JSON для извлечения данных внутри Asynctask. Я должен объявить AsyncTask внутри MainAcitivity.java, в противном случае NullPointerException, если я создам новый класс для AsyncTask. Я объявил метод внутри класса адаптера

public void setData(List<Certifications> data){
//List<Certifications> mCertification;
 mCertifications = data;
 notifyDataSetChanged();}

Я также следую за постом Вишваната Кумара Санду, и вот мой 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
0 голосов
/ 07 октября 2019

Позвоните

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();
  }  

}
...