应用程序不在使用Asynctask的调试模式时崩溃

时间:2019-04-30 18:59:26

标签: android android-asynctask

我创建了一个可在单击按钮后从url读取数据的应用。

然后,我使用这些数据在新活动中显示其中一些。

通过使用ASynctask如下读取URL:

line-height

主要代码如下:

package com.example.test;

import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

public class Read_URL extends AsyncTask<Void,Void,Void> {

    String data = "";
    String [] list;

    ArrayList <String>  hiscore_skill_rank = new ArrayList<>();
    ArrayList <String>  hiscore_skill_level = new ArrayList<>();
    ArrayList <String>  hiscore_skill_exp = new ArrayList<>();

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

        try {
            URL url = new URL("https://......");
            HttpURLConnection httpURLConnection =(HttpURLConnection) url.openConnection();

            InputStream inputStream = httpURLConnection.getInputStream();

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            for (int j = 0; j <24; j++) {
                line = bufferedReader.readLine();
                data = data + line;

                list = line.split(",");

                hiscore_skill_rank.add(list[0]);
                hiscore_skill_level.add(list[1]);
                hiscore_skill_exp.add(list[2]);

            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

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

    }
}

process.execute的结果是3个24个变量的数组列表。

我的问题是,当我启动该应用程序时,它崩溃了,但是当我以调试模式启动它时,一切正常。

我在想,也许是因为在常规模式下读取URL需要花费时间,所以它不知道显示什么,但是在调试模式下,它有更多时间来完成从url获取信息的操作。

如果没有完成读取数据的操作,读取URL会导致应用崩溃吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

问题在于此方法:

    public void openHiScore(){

        Read_URL process = new Read_URL();
        process.execute();

        Intent intent = new Intent(this,HiScore.class);

        intent.putStringArrayListExtra("hiscore_skill_rank",process.hiscore_skill_rank);
        intent.putStringArrayListExtra("hiscore_skill_level",process.hiscore_skill_level);
        intent.putStringArrayListExtra("hiscore_skill_exp",process.hiscore_skill_exp);
        intent.putExtra("name",name.getText().toString());

        startActivity(intent);

    }

process.execute()将启动异步任务,但随后在doInBackground代码运行之前立即继续创建新的Intent。如果可能,您应该尝试将所有Intent / startActivity代码移至Read_URL类的onPostEvent中。或者,在您的主活动中创建一个回调函数,Read_Url可以从onPostEvent调用该回调函数,该函数将把Main中的所有Intent / startActivity东西都做完。

这里是如何集成回调函数的示例。为了简化操作,我将Read_URL设置为在MainActivity类内部定义的内部类。

MainActivity.java

            // Imports from MainActivity
            import android.content.Intent;
            import android.support.v7.app.AppCompatActivity;
            import android.os.Bundle;
            import android.view.View;
            import android.widget.Button;
            import android.widget.EditText;

            // Imports from Read_URL
            import android.os.AsyncTask;
            import java.io.BufferedReader;
            import java.io.IOException;
            import java.io.InputStream;
            import java.io.InputStreamReader;
            import java.net.HttpURLConnection;
            import java.net.MalformedURLException;
            import java.net.URL;
            import java.util.ArrayList;


            public class MainActivity extends AppCompatActivity {
                Button button;
                EditText name;
                public Activity myActivity;

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

                    button = findViewById(R.id.continue_button);
                    name = findViewById(R.id.username_text);
                    myActivity = this;

                    button.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            openHiScore();
                        }
                    });
                }

                public void openHiScore(){

                    Read_URL process = new Read_URL();
                    process.execute();


                }

                public void processResults(ArrayList hiscore_skill_rank, ArrayList hiscore_skill_level, ArrayList hiscore_skill_exp) {

                    Intent intent = new Intent(this,HiScore.class);

                    intent.putStringArrayListExtra("hiscore_skill_rank",hiscore_skill_rank);
                    intent.putStringArrayListExtra("hiscore_skill_level",hiscore_skill_level);
                    intent.putStringArrayListExtra("hiscore_skill_exp",hiscore_skill_exp);
                    intent.putExtra("name",name.getText().toString());

                    startActivity(intent);

                }                       


                // I think you can include the Read_URL class inside of your MainActivity class
                // In that way, it can access the public variables declared in the MainActivity class

                public class Read_URL extends AsyncTask<Void,Void,Void> {

                    String data = "";
                    String [] list;

                    ArrayList <String>  hiscore_skill_rank = new ArrayList<>();
                    ArrayList <String>  hiscore_skill_level = new ArrayList<>();
                    ArrayList <String>  hiscore_skill_exp = new ArrayList<>();

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

                        try {
                            URL url = new URL("https://......");
                            HttpURLConnection httpURLConnection =(HttpURLConnection) url.openConnection();

                            InputStream inputStream = httpURLConnection.getInputStream();

                            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

                            String line;
                            for (int j = 0; j <24; j++) {
                                line = bufferedReader.readLine();
                                data = data + line;

                                list = line.split(",");

                                hiscore_skill_rank.add(list[0]);
                                hiscore_skill_level.add(list[1]);
                                hiscore_skill_exp.add(list[2]);

                            }
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        return null;
                    }

                    @Override
                    protected void onPostExecute(Void aVoid) {
                        super.onPostExecute(aVoid);
                        myActivity.processResults(hiscore_skill_rank, hiscore_skill_level, hiscore_skill_exp);

                    }
                } // end of Read_URL
            }  // end of MainActivity