Приложение вылетает, когда не в режиме отладки с использованием Asynctask - PullRequest
0 голосов
/ 30 апреля 2019

Я создал приложение, которое считывает данные из URL после нажатия кнопки.

Затем я использую эти данные для отображения некоторых из них в новом упражнении.

Чтение URL выполняется с помощью ASynctask следующим образом:

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

    }
}

Где основной код выглядит следующим образом:

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;

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

    @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);

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

        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 - 3 массива из 24 переменных.

Моя проблема в том, что когда я запускаю приложение, оно падает, однако, когда я запускаю его в режиме отладки, все работает.

Я подумал, может быть, поскольку для чтения URL в обычном режиме требуется время, он не знает, что отображать, однако, когда в режиме отладки у него есть больше времени, чтобы завершить получение информации из URL.

Есть ли причина, по которой чтение URL может привести к сбою приложения, если оно не завершило чтение данных?

Спасибо!

1 Ответ

0 голосов
/ 30 апреля 2019

Проблема с этим методом:

    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 / startActivity в onPostEvent класса Read_URL. Или создайте в вашем основном действии функцию обратного вызова, которую Read_Url может вызывать из onPostEvent, и эта функция будет выполнять все действия Intent / startActivity обратно в Main.

Вот пример того, как интегрировать функцию обратного вызова. Чтобы сделать это проще, я делаю 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...