在doInBackground中使用OkHttpClient时应用程序崩溃

时间:2017-09-17 16:08:46

标签: java android okhttp

我在Android LOLLIPOP上的应用程序运行良好,但在较低版本中,程序崩溃并显示此错误:

  

抓住了异常                                                                       java.lang.RuntimeException:执行doInBackground()

时发生错误

并指出这行代码:

OkHttpClient client = new OkHttpClient();

这是我的代码:

private void getMoviesFromDBz(int id) {

    AsyncTask<Integer, Void, Void> asyncTask = new AsyncTask<Integer, Void, Void>() {



        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }


        @Override
        protected Void doInBackground(Integer... movieIds) {

            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url(linkkk + movieIds[0])
                    .build();
            try {
                Response response = client.newCall(request).execute();

                JSONArray array = new JSONArray(response.body().string());

                for (int i = 0; i < array.length(); i++) {

                    JSONObject object = array.getJSONObject(i);

                    Movie movie = new Movie(object.getInt("id") , object.getString("per") , object.getString("movie_name"),
                            object.getString("movie_image"), object.getString("movie_genre") , object.getString("movie_discription") , object.getString("movie_lat"), object.getString("movie_lon") , object.getString("movie_marker") , object.getString("sort") , object.getString("price") , object.getString("email") , object.getString("tell") , object.getString("location") , object.getString("count"));


                    ItemOneFragment.this.movies2.add(movie);
                }


            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            adapter2.notifyDataSetChanged();
            getMoviesFromDB(0);
        }
    };

    asyncTask.execute(id);
    scroll2 = 1;
}

3 个答案:

答案 0 :(得分:2)

您尝试在后台线程中访问Main / UI Thread:

ItemOneFragment.this.movies2.add(movie);

只需返回movie对象并在onPostExecute()方法上执行上一行,我也不建议为每个请求实例化OkHttpClient

答案 1 :(得分:0)

您正尝试在后台线程的UI线程上执行操作。所以你可以使用runonuithread

runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                         ItemOneFragment.this.movies2.add(movie);
                    }
                });

在代码中查看以下更改。

    @Override
    protected Void doInBackground(Integer... movieIds) {

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(linkkk + movieIds[0])
                .build();
        try {
            Response response = client.newCall(request).execute();

            JSONArray array = new JSONArray(response.body().string());

            for (int i = 0; i < array.length(); i++) {

                JSONObject object = array.getJSONObject(i);

                Movie movie = new Movie(object.getInt("id") , object.getString("per") , object.getString("movie_name"),
                        object.getString("movie_image"), object.getString("movie_genre") , object.getString("movie_discription") , object.getString("movie_lat"), object.getString("movie_lon") , object.getString("movie_marker") , object.getString("sort") , object.getString("price") , object.getString("email") , object.getString("tell") , object.getString("location") , object.getString("count"));


                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                         ItemOneFragment.this.movies2.add(movie);
                    }
                });
            }


        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

我认为这可以解决您的问题。

答案 2 :(得分:0)

你不需要任何带有Okhttp的Asynctask

查找examples that use the enqueue method

// Build the client and request in the main thread 

// Start an asynchronous method 
client.newCall(request).enqueue(new Callback() {
    @Override public void onResponse(Call call, Response response) throws IOException {
        try (ResponseBody responseBody = response.body()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

       JSONObject json = new JSONObject(responseBody.string());
      }
    }
});

如果你想使用Okhttp的JSON对象,Retrofit将是一个更好的库