应用程序崩溃而无法执行AsyncTask

时间:2018-04-30 13:21:59

标签: java android json android-asynctask

我的应用中遇到AsyncTask问题。 AsyncTask位于SplashScreenAcivity.java。它使用json为MainActivity.java下载数据,同时显示启动画面。加载数据后,应用程序会显示MainActivity屏幕。但是,当我关闭互联网连接应用程序崩溃。而不是它,我想转移到MainActivity.java,并显示必须打开互联网连接的吐司。 SplashScreen.java在MainActivity中加载listView的数据。

SplashActivityScreen.java

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

    new DownloadData().execute();

}

private class DownloadData extends AsyncTask<Void, Void, Void> {



    @Override
    protected Void doInBackground(Void... voids) {

                SyncHttpClient clientOne = new SyncHttpClient();
                clientOne.get("https://api.themoviedb.org/3/tv/top_rated?api_key=d253f520df9cd868af7db8daaa0db8fb&language=en-US", new JsonHttpResponseHandler() {

                    @Override
                    public void onSuccess(int statusCode, Header[] headers, JSONObject response) {

                        try {

                            tvseries0 = response.getJSONArray("results").getJSONObject(0).getString("name");
                            tvseries1 = response.getJSONArray("results").getJSONObject(1).getString("name");
                            tvseries2 = response.getJSONArray("results").getJSONObject(2).getString("name");
                            tvseries3 = response.getJSONArray("results").getJSONObject(3).getString("name");
                            tvseries4 = response.getJSONArray("results").getJSONObject(4).getString("name");
                            tvseries5 = response.getJSONArray("results").getJSONObject(5).getString("name");
                            tvseries6 = response.getJSONArray("results").getJSONObject(6).getString("name");
                            tvseries7 = response.getJSONArray("results").getJSONObject(7).getString("name");
                            tvseries8 = response.getJSONArray("results").getJSONObject(8).getString("name");
                            tvseries9 = response.getJSONArray("results").getJSONObject(9).getString("name");
                            tvseries10 = response.getJSONArray("results").getJSONObject(10).getString("name");
                            tvseries11 = response.getJSONArray("results").getJSONObject(11).getString("name");
                            tvseries12 = response.getJSONArray("results").getJSONObject(12).getString("name");
                            tvseries13 = response.getJSONArray("results").getJSONObject(13).getString("name");
                            tvseries14 = response.getJSONArray("results").getJSONObject(14).getString("name");
                            tvseries15 = response.getJSONArray("results").getJSONObject(15).getString("name");
                            tvseries16 = response.getJSONArray("results").getJSONObject(16).getString("name");
                            tvseries17 = response.getJSONArray("results").getJSONObject(17).getString("name");
                            tvseries18 = response.getJSONArray("results").getJSONObject(18).getString("name");
                            tvseries19 = response.getJSONArray("results").getJSONObject(19).getString("name");

                        } catch (JSONException e) {

                            e.printStackTrace();

                        }

                    }

                    @Override
                    public void onFailure(int statusCode, Header[] headers,Throwable e , JSONObject response) {

                        Toast.makeText(SplashScreenActivity.this, "Turn on the internet and swipe to refresh.", Toast.LENGTH_SHORT).show();

                    }
                });

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        Intent i = new Intent(getApplicationContext(), MainActivity.class);

        i.putExtra("tvseries0", tvseries0);
        i.putExtra("tvseries1", tvseries1);
        i.putExtra("tvseries2", tvseries2);
        i.putExtra("tvseries3", tvseries3);
        i.putExtra("tvseries4", tvseries4);
        i.putExtra("tvseries5", tvseries5);
        i.putExtra("tvseries6", tvseries6);
        i.putExtra("tvseries7", tvseries7);
        i.putExtra("tvseries8", tvseries8);
        i.putExtra("tvseries9", tvseries9);
        i.putExtra("tvseries10", tvseries10);
        i.putExtra("tvseries11", tvseries11);
        i.putExtra("tvseries12", tvseries12);
        i.putExtra("tvseries13", tvseries13);
        i.putExtra("tvseries14", tvseries14);
        i.putExtra("tvseries15", tvseries15);
        i.putExtra("tvseries16", tvseries16);
        i.putExtra("tvseries17", tvseries17);
        i.putExtra("tvseries18", tvseries18);
        i.putExtra("tvseries19", tvseries19);

        startActivity(i);

        finish();

    }
}

}

崩溃1

04-30 13:15:35.165 12349-12365/przemo.me.recommend.recommendme E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: przemo.me.recommend.recommendme, PID: 12349
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:318)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761)
 Caused by: java.lang.RuntimeException: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at com.loopj.android.http.AsyncHttpResponseHandler.onUserException(AsyncHttpResponseHandler.java:304)
    at com.loopj.android.http.AsyncHttpResponseHandler.handleMessage(AsyncHttpResponseHandler.java:395)
    at com.loopj.android.http.AsyncHttpResponseHandler.sendMessage(AsyncHttpResponseHandler.java:401)
    at com.loopj.android.http.AsyncHttpResponseHandler.sendFailureMessage(AsyncHttpResponseHandler.java:319)
    at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:109)
    at com.loopj.android.http.SyncHttpClient.sendRequest(SyncHttpClient.java:95)
    at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1078)
    at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1037)
    at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:64)
    at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:56)
    at android.os.AsyncTask$2.call(AsyncTask.java:304)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:761) 
 Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:200)
    at android.os.Handler.<init>(Handler.java:114)
    at android.widget.Toast$TN.<init>(Toast.java:346)
    at android.widget.Toast.<init>(Toast.java:101)
    at android.widget.Toast.makeText(Toast.java:260)
    at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData$1.onFailure(SplashScreenActivity.java:103)
    at com.loopj.android.http.JsonHttpResponseHandler.onFailure(JsonHttpResponseHandler.java:233)
    at com.loopj.android.http.AsyncHttpResponseHandler.handleMessage(AsyncHttpResponseHandler.java:359)
    at com.loopj.android.http.AsyncHttpResponseHandler.sendMessage(AsyncHttpResponseHandler.java:401) 
    at com.loopj.android.http.AsyncHttpResponseHandler.sendFailureMessage(AsyncHttpResponseHandler.java:319) 
    at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:109) 
    at com.loopj.android.http.SyncHttpClient.sendRequest(SyncHttpClient.java:95) 
    at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1078) 
    at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1037) 
    at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:64) 
    at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:56) 
    at android.os.AsyncTask$2.call(AsyncTask.java:304) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:761) 

崩溃2

04-30 13:15:35.162 12349-12365/przemo.me.recommend.recommendme E/AsyncHttpRH: User-space exception detected!
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:200)
    at android.os.Handler.<init>(Handler.java:114)
    at android.widget.Toast$TN.<init>(Toast.java:346)
    at android.widget.Toast.<init>(Toast.java:101)
    at android.widget.Toast.makeText(Toast.java:260)
    at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData$1.onFailure(SplashScreenActivity.java:103)
    at com.loopj.android.http.JsonHttpResponseHandler.onFailure(JsonHttpResponseHandler.java:233)
    at com.loopj.android.http.AsyncHttpResponseHandler.handleMessage(AsyncHttpResponseHandler.java:359)
    at com.loopj.android.http.AsyncHttpResponseHandler.sendMessage(AsyncHttpResponseHandler.java:401)
    at com.loopj.android.http.AsyncHttpResponseHandler.sendFailureMessage(AsyncHttpResponseHandler.java:319)
    at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:109)
    at com.loopj.android.http.SyncHttpClient.sendRequest(SyncHttpClient.java:95)
    at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1078)
    at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1037)
    at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:64)
    at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:56)
    at android.os.AsyncTask$2.call(AsyncTask.java:304)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761)

4 个答案:

答案 0 :(得分:3)

您无法从非UI线程执行UI操作。就像在你的代码中一样,你在异步任务线程中显示Toast。

你应该替换

Toast.makeText(SplashScreenActivity.this, "Turn on the internet and swipe to refresh.", Toast.LENGTH_SHORT).show();     

用这个

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(SplashScreenActivity.this, "Turn on the internet and swipe to refresh.", Toast.LENGTH_SHORT).show();     
        }
    });

答案 1 :(得分:1)

使用 -

SplashScreenActivity.this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(SplashScreenActivity.this, "Turn on the internet and swipe to refresh.", Toast.LENGTH_SHORT).show();     
        }
    });

答案 2 :(得分:1)

这是我多年前在Android Java中创建的服务器连接AsyncTask任务。后台任务成功运行。我用它来在后台更新我当时开发的App中的数据存储库。

public class DataExchangeStore extends Application {
    public void startServerConnection(Context contextGlobal, Activity activityGlobal) {
        this.contextGlobal = contextGlobal;
        this.activityGlobal = activityGlobal;
        connectTask = new ConnectTask();
        connectTask.execute("");
    }

    private ConnectTask connectTask;

    public class ConnectTask extends AsyncTask<String, String, TCPClient> {
        @Override
        protected TCPClient doInBackground(String... message) {
            android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_BACKGROUND);
            // we create a TCPClient object
            mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
                @Override
                // here the messageReceived method is implemented
                public void messageReceived(ChatMessage message) {
                    // this method calls the onProgressUpdate
                    publishProgress(message.getMessage());
                }
            }, contextGlobal, activityGlobal);
            mTcpClient.run();
            return null;
        }
        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
            System.err.println(values[0]);
            // do your stuff here
        }
    }

导入是永久锁定活动的屏幕方向,使用纵向横向指定 Android-Manifest 文件中的screenOrientation属性值:

<activity android:screenOrientation="portrait" />

答案 3 :(得分:0)

虽然以前的答案没有错,但是使用runOnUiThread()跳出AsyncTask中的后台线程并不是一个好习惯。你有onPostExecute()方法。

您应该做的是将结果对象传递给onPostExecute()。该对象将封装结果状态(即:错误或成功)和接收的实际数据。然后在onPostExecute()中检查结果状态并在状态为错误时显示Toast。

并帮自己一个忙,用List<TvSerie>替换你的20个TvSerie对象,并在你的AsyncTask中循环填充列表。

有关如何正确使用它的详细信息,请参阅the AsyncTask documentation