Подтвердить что ты не робот

Android - AsyncTask не выполняется

Я знаю, что с этим заголовком уже много вопросов, но я до сих пор не нашел решения для своего дела.

У меня есть следующий код, который получает данные пользователей из онлайн-базы данных. Проблема заключается, как указано в заголовке, в том, что AsyncTask не запускается.

Здесь мой код:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getData(); // retrieves "friends" data from database
    FloatingActionButton btn3 = (FloatingActionButton) findViewById(R.id.button_add_new_friend);
    btn3.setBackgroundTintList(getResources().getColorStateList(R.color.Blonde));
    btn3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            LayoutInflater layoutInflater = LayoutInflater.from(profile.this);
            View promptView = layoutInflater.inflate(R.layout.input_new_friend, null);
            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(profile.this);
            alertDialogBuilder.setView(promptView);

            final EditText editText1 = (EditText) promptView.findViewById(R.id.edittext_addnewfriend);

            // setup a dialog window
            alertDialogBuilder.setCancelable(false)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
                        StrictMode.setThreadPolicy(policy);

                        InputStream is = null;

                        // add values to the database
                        String friend = "" + editText1.getText();

                        // Verify the user in the USERS database - get users data from the dabase
                        GetDataJSON g = new GetDataJSON();
                        g.execute();                                
                        if (friends.contains(friend)) // if you are already friends with that user
                            Toast.makeText(getApplicationContext(), "You are already friends with that user!",
                                Toast.LENGTH_LONG).show();
                        else {
                            if (!users.contains(friend)) // the user doesn't exist in our database
                                Toast.makeText(getApplicationContext(), "That user doesn't exist! You either haven't introduced the right email or he not a registered user within Poinder.",
                                    Toast.LENGTH_LONG).show();
                        else // the user exists so we add him to the friends list
                        {
                            //do something
                        }
}

// Getting the users
protected void showList2(){
    try {
        JSONObject jsonObj = new JSONObject(myJSON);
        people = jsonObj.getJSONArray(TAG_RESULTS);

        for(int i=0;i<people.length();i++){
            JSONObject c = people.getJSONObject(i);
            String user = c.getString(TAG_USER);
            String email = c.getString(TAG_EMAIL);
            Double location_latitude = c.getDouble(TAG_LATITUDE);
            Double location_longitude = c.getDouble(TAG_LONGITUDE);

            users.add(email);
        }

    } catch (JSONException e) {
        e.printStackTrace();
    }

}

// Getting the users
private class GetDataJSON extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... params) {
        DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
        HttpPost httppost = new HttpPost("http://xxxxxxx/friends_out.php");

        // Depends on your web service
        httppost.setHeader("Content-type", "application/json");

        InputStream inputStream = null;
        String result = null;
        try {
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();

            inputStream = entity.getContent();
            // json is UTF-8 by default
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
            StringBuilder sb = new StringBuilder();

            String line = null;
            while ((line = reader.readLine()) != null)
            {
                sb.append(line + "\n");
            }
            result = sb.toString();
        } catch (Exception e) {
            // Oops
        }
        finally {
            try{if(inputStream != null)inputStream.close();}catch(Exception squish){}
        }
        return result;
    }

    @Override
    protected void onPostExecute(String result){
        myJSON=result;
        showList2();
    }
}

Любая идея, какой другой метод я должен использовать вместо этого? Или, желательно, как я должен изменить это, чтобы работать, и любые идеи, почему мой AsyncTask никогда не запускается?

EDIT: я применил все предложения, упомянутые ниже, и, к сожалению, никто из них не работает до сих пор (мой AsyncTask все еще не запускается).

И еще один вопрос: использование более одного AsyncTask в том же действии имеет какое-то отношение к моей проблеме?

4b9b3361

Ответ 1

Поскольку (я полагаю) ни одно из предложенных решений не работает, я подозреваю, что ваша проблема заключается в том, как AsyncTask. Если несколько AsyncTasks выполняются в одном и том же Activity, как в вашем приложении, то эти AsyncTasks не будут выполняться параллельно. Они будут выполнять один за другим.

Я подозреваю, что другие ваши AsyncTask долго работают, так что ваш GetDataJSON AsyncTask ожидает завершения других задач.

Решение состоит в том, чтобы включить параллельное выполнение AsyncTask. Используйте следующий код для параллельного выполнения AsyncTasks.

GetDataJSON g = new GetDataJSON();
g.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

Из документов AsyncTask:

Порядок исполнения

При первом представлении AsyncTasks выполнялись последовательно в одном фоновом потоке. Начиная с DONUT, это было изменено на пул потоков, позволяющий нескольким задачам работать параллельно. Начиная с HONEYCOMB, задачи выполняются в одном потоке, чтобы избежать распространенных ошибок приложения, вызванных параллельным выполнением.

Если вы действительно хотите параллельное выполнение, вы можете вызвать executeOnExecutor (java.util.concurrent.Executor, Object []) с THREAD_POOL_EXECUTOR.

Надеюсь это поможет.

Ответ 2

просто измените параметры асинтеза

 class GetDataJSON extends AsyncTask<String, Void, String>

to,

 class GetDataJSON extends AsyncTask<Void, Void, String>

Ответ 3

Из вашего вопроса я пришел к выводу, что вы пытаетесь получить список друзей с сервера и на основе результата вы увидите сообщение Toast.

В соответствии с вашим кодом вы не создаете и не показываете AlertDialog из alertDialogBuilder. Попробуйте показать AlertBox.

Как AsyncTask запускается в отдельном потоке. Следовательно,

if (friends.contains(friend)) 

немедленно выполнится после

 g.execute();

Итак, даже пользователь находится в списке друзей, он покажет Toast части else.

Кроме того, вы не помещали журналы в методы Asynctask, это может создать впечатление, что AsyncTask не запущен.

Я предлагаю вам переместить код условия if с AlertDialog на onPostExecute() метод GetDataJSON и поместить его после showList2();. Кроме того, поместите некоторые журналы в методы AsyncTask.

Надеюсь, это поможет. Пожалуйста, найдите приведенный ниже код для справки:

public class AIssue extends Activity {
String result = " DATA";

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.some);
    findViewById(R.id.button1).setOnClickListener(
            new View.OnClickListener() {

                @Override
                public void onClick(View arg0) {
                    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                            .permitAll().build();
                    StrictMode.setThreadPolicy(policy);

                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                            AIssue.this);
                    alertDialogBuilder.setCancelable(false);
                    alertDialogBuilder.setPositiveButton("OK",
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog,
                                        int which) {
                                    GetDataJSON g = new GetDataJSON();
                                    g.execute();

                                }
                            });
                    alertDialogBuilder.create().show();
                }
            });
}

// Getting the users
private class GetDataJSON extends AsyncTask<Void, Void, String> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.e("IN", "ONPRE EXECUTE");
    }

    @Override
    protected String doInBackground(Void... params) {
        String result = "SOME DATA";
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(1000);
                Log.e("IN", "DO IN BACKGROUND");
            } catch (InterruptedException e) {
                e.printStackTrace();
                result = "ERROR";
            }

        }
        return result;
    }

    @Override
    protected void onPostExecute(String result) {
        Log.e("IN", "ON POST EXECUTE");
        Log.e("IN", "" + result);
        /*****
         * Your Condition to Check The Friend should be here after
         * showList2();
         * ***/
        if (result.equalsIgnoreCase("SOME DATA"))// replace it with your
                                                    // condition to check
                                                    // friends
        {
            Log.e("IN", "IF");
        } else {
            Log.e("IN", "ELSE");
        }
    }
}
}

Ответ 4

Внутри метода getData2() попробуйте следующее:

new AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            // your code
        }

        @Override
        protected void onPostExecute(String result){
           // your code
        }
    }.execute();

или если это не сработает, поместите метод класса AsyncTask вне метода, а затем непосредственно сделайте вызов для выполнения класса AsyncTask вместо getData2(), как этот

new GetDataJSON().execute();

Ответ 5

добавьте этот метод переопределения в задачу Aysc.

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

        }

Я не знаю, что вы пытаетесь сделать здесь, но этот код будет выполнен до завершения асинхронной задачи.

if (friends.contains(friend)) // if you are already friends with that user
                                        Toast.makeText(getApplicationContext(), "You are already friends with that user!",
                                                Toast.LENGTH_LONG).show();
                                    else {
                                        if (!users.contains(friend)) // the user doesn't exist in our database
                                            Toast.makeText(getApplicationContext(), "That user doesn't exist! You either haven't introduced the right email or he not a registered user within Poinder.",
                                                    Toast.LENGTH_LONG).show();
                                        else // the user exists so we add him to the friends list
                                        {
                                            //do something
                                        }

Если вы хотите, чтобы этот код выполнялся после завершения задачи asyc asyc, добавьте этот код внутри метода ur showList2().

Кстати, почему u r создает задачу async внутри внутреннего метода. Его плохая идея. Создайте отдельную задачу aynch. так что u может использовать из другого действия.

Ответ 6

Добавить конструктор в AsyncTask

public GetDataJSON (){
}

Добавьте его onPreExecute, чтобы быть более уверенным

@Override
    protected void onPreExecute() {
    super.onPreExecute();
    Toast.makeText(this /*or getActivity()*/,"IT WORKING!!!", Toast.LENGTH_LONG).show();

    }

Ответ 7

Я не думаю, что принуждение Strict Mode помогает в этой ситуации. Вы должны использовать AsyncTask вместо строкового режима при кодировании сетевых операций (например, тех, которые вы делаете внутри метода doInBackground), поэтому ваш пользовательский интерфейс не блокируется.

Строгий режим заставит операции запускаться в основном потоке приложения, в то время как AsyncTask работает в фоновом потоке.

Ответ 8

Проблема заключается в ваших параметрах асинтетики

Документация Google Android. Говорит, что:

Асинхронная задача определяется тремя универсальными типами, называемыми Params, Progress и Result, и 4 шагами, называемыми onPreExecute, doInBackground, onProgressUpdate и onPostExecute.

Общие типы AsyncTask:

Три типа, используемые асинхронной задачей, следующие:

Документация Google Android. Говорит, что:

Общие типы AsyncTask:

Три типа, используемые асинхронной задачей, следующие:

  • Парамс, тип параметров, отправленных в задачу при выполнении.
  • Прогресс, тип единиц прогресса, опубликованных во время фоновое вычисление.
  • Результат, тип результата фонового вычисления.

Не все типы всегда используются асинхронной задачей. Чтобы отметить тип как неиспользуемый, просто используйте тип Void:

 private class MyTask extends AsyncTask<Void, Void, Void> { ... }

Итак, поскольку вы не отправляете какие-либо параметры в AsyncTask, выполните задачу async, как показано ниже

 // Getting the users
    public void getData2(){
   new GetDataJSON().execute();  
    }


class GetDataJSON extends AsyncTask<Void, Void, String> {

            @Override
            protected String doInBackground(Void... params) {
                /// your logic here
                return result;
            }

            @Override
            protected void onPostExecute(String result){
                // your logic here
            }
        }

Ответ 9

Решение этой проблемы, вполне обычное, которое я представил в моей текущей разработке, - это AsyncService, я не буду использовать все функции этой библиотеки (системы ache), но мощно, а также поможет вам очистить код в вашей деятельности.

  • Вы объявляете свой сервис, который будет извлекать данные, с аннотацией @AsyncService
  • Вы вводите услугу в свою деятельность.
  • Позвоните в службу поддержки, где вам нужно.
  • Объявить метод внутри вашей деятельности с помощью аннотации @OnMessage, где вы собираетесь иметь дело с ответом службы...

AsyncService GitHub Wiki

Я не знаю, существует ли другое решение, которое помогает разработчикам разделить проблемы и очистить код (в Android, я имею в виду), как это, это лучшие результаты, которые я пробовал, и, возможно, вы тоже должны попробовать. Конечно, это поможет вам в решении текущей проблемы.

Надеюсь, что это поможет.