Android - RecyclerView: адаптер не подключен; ошибка пропуска макета

Я кодирую приложение, которое показывает рейтинг коробки, получая API файла Json все нормально работает, если я прокомментирую коды про Recyclerview. Код адаптера в порядке, я думаю ............................................ .................................................. .................................................. ...... если нет, logcat говорит так:

08-03 09:53:59.915 8189-8189/kr.ac.mju.mju_alimi E/RecyclerView: No adapter attached; skipping layout
08-03 09:54:00.351 8189-8189/kr.ac.mju.mju_alimi E/AndroidRuntime: FATAL EXCEPTION: main
    Process: kr.ac.mju.mju_alimi, PID: 8189
    java.lang.NullPointerException: Attempt to get length of null array
        at kr.ac.mju.mju_alimi.MainActivity$MyAsyncTask.onPostExecute(MainActivity.java:152)
        at kr.ac.mju.mju_alimi.MainActivity$MyAsyncTask.onPostExecute(MainActivity.java:97)

Я думаю, что порядок кодов неправильный, но точно не знаю ... MainActivity.java - это ...:

public class MainActivity extends AppCompatActivity {


    public static final String TAG = "MainActivity";
    TextView tv_result;

    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    ArrayList<MovieItem> itemArrayList;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        //array list
        itemArrayList = new ArrayList<>(); //데이터

        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(mLayoutManager);

//        tv_result = (TextView) findViewById(R.id.tv_result);
//        tv_result.setMovementMethod(new ScrollingMovementMethod()); //스크롤기능 추가하기

        MyAsyncTask mProcessTask = new MyAsyncTask();
        mProcessTask.execute();


        android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);

        toolbar.findViewById(R.id.menu).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PopupMenu pop = new PopupMenu(MainActivity.this, v);
                pop.getMenuInflater().inflate(R.menu.menu, pop.getMenu());
                pop.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return false;
                    }
                });
                pop.show();
            }

        });

        ImageButton b = (ImageButton) findViewById(R.id.bell);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, Pop.class));
            }
        });

    }


    //AsyncTask 생성 - 모든 네트워크 로직을 여기서 작성해 준다.
    public class MyAsyncTask extends AsyncTask<String, Void, MovieItem[]> {
        ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);

        //OkHttp 객체생성
        OkHttpClient client = new OkHttpClient();

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setMessage("\t로딩중...");
            //show dialog
            progressDialog.show();
        }

        @Override
        protected MovieItem[] doInBackground(String... params) {

            HttpUrl.Builder urlBuilder = HttpUrl.parse("http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json").newBuilder();
            urlBuilder.addQueryParameter("key","430156241533f1d058c603178cc3ca0e");
            urlBuilder.addQueryParameter("targetDt","20170908");
            String url = urlBuilder.build().toString();

            Request request = new Request.Builder()
                    .url(url)
                    .build();

            try {
                Response response = client.newCall(request).execute();

                Gson gson = new GsonBuilder().create();
                JsonParser parser = new JsonParser();


                JsonElement rootObject = parser.parse(response.body().charStream())
                        .getAsJsonObject().get("boxOfficeResult").getAsJsonObject().get("dailyBoxOfficeList"); 
                MovieItem[] posts = gson.fromJson(rootObject, MovieItem[].class);

                return posts;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(MovieItem[] result) {
            super.onPostExecute(result);
            progressDialog.dismiss();

            if (result.length > 0){
                for (MovieItem post: result){
                    itemArrayList.add(post);

                }
            }

            mAdapter = new Adapter(itemArrayList);
            mRecyclerView.setAdapter(mAdapter);
        }
    }

}
0
0
253
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы настраиваете адаптер после вызова асинхронной задачи. Это означает, что каждый раз, когда вызывается задача async, адаптер представления ресайклера изменяется. В этом нет необходимости, поскольку вы используете только один адаптер. Лучше всего инициализировать адаптер onCreate, а затем просто уведомить адаптер о том, что его набор данных изменился, когда вы изменили значения списка.


TL; DR

Переместите этот код в свой при создании:

mAdapter = new Adapter(itemArrayList);
mRecyclerView.setAdapter(mAdapter);

И замените это там, где изначально был этот код (P.S. используйте intellisense, чтобы выяснить, правильная ли это функция, ключевые слова - поставить в известность, набор данных и измененный):

mAdapter.notifyDataSetChanged()

Другие вопросы по теме