Как я могу остановить асинхронные задачи, которые зацикливаются в фоновом режиме Android после вызова onPause ()? - PullRequest
0 голосов
/ 10 февраля 2019

Я использую пакет com.hierynomus.smbj.share;подключиться через smb2 к сетевому расположению, чтобы проверить его подключение, однако оно запускается только в начале моей деятельности (в фоновом режиме).

Я добавил прослушиватель для возврата после того, как задача вернула строкуЗначение (ошибка, успех), как только вызывается прослушиватель в действии (я вызвал задачу), я затем создаю новый экземпляр состояния подключения (это зацикливает его)

Вот как я проверяюсоединение в onCreate () действия

//Global ConnectionStatus connectionStatus;

        connectionStatus = new ConnectionStatus();
        connectionStatus.setContext(this);
        connectionStatus.setListener(this);
        connectionStatus.setCon(databaseReadWrite.getMydbc());
        connectionStatus.execute("CheckDatabase", "nodelay");

Вот как я пытаюсь отменить задачу при открытии другого действия

  protected void onPause() {
        delay.equals("cancel");
        super.onPause();
        MyApplication.activityPaused();
        if (connectionStatus != null) {
            connectionStatus.cancel(true);

        }
        hasRun = false;

    }

Затем это выполняется в том же действии послеасинхронная задача завершена, поэтому я перезапустил новый экземпляр connectionStatus

@Override
    public void onTaskCompleted(String result) {
            ActionBar actionBar = this.getSupportActionBar();
            String title = getTitle().toString();
            String code = handlingFunctions.getResultCode(result);
            if (code.equals("1")) {
                Message.message(this, " Database connected to server!");
                setTitle(title + result);
            } else if (code.equals("2")) {
                actionBar.setBackgroundDrawable(new ColorDrawable(Color.RED));
                alertDialog.message(this, result);
            } else if (code.equals("0")) {
                actionBar.setBackgroundDrawable(new ColorDrawable(Color.RED));
                setTitle(title + " Database connected in offline mode");
                alertDialog.message(this, result);
            } else if (code.equals("3")) {
                //alertDialog.message(this, result);
                imageStatus.setText(result);
            } else if (code.equals("4")) {
                imageStatus.setText(result);
            }
            connectionStatus = new ConnectionStatus();
            connectionStatus.setContext(getApplicationContext());
            connectionStatus.setListener(AllParts.this);
            connectionStatus.setCon(databaseReadWrite.getMydbc());
            connectionStatus.execute("CheckDatabase", "delay");

        }
    }



  public class ConnectionStatus extends AsyncTask<String, Void, String> {

    private OnConnectionStatusComplete listener;
    private ArrayList<String> imageNames;
    private ArrayList<ImageDetails> currentImageDetails;
    private SQLiteConnection sqLiteConnection;
    private Context context;

    public void setListener(OnConnectionStatusComplete listen) {
        this.listener = listen;
    }

    public void setImageNames(ArrayList<String> ImageNames) {
        this.imageNames = ImageNames;
    }

    public void setCurrentDetails(ArrayList<ImageDetails> details) {
        this.currentImageDetails = details;
    }

    @Override
    protected void onPostExecute(String s) {
        listener.onTaskCompleted(s);
    }

    public void setContext(Context mContext) {
        context = mContext;
    }

    public void setCon(SQLiteConnection sqlite) {
        sqLiteConnection = sqlite;
    }

     @Override
    protected String doInBackground(String... strings) {
         if(this.isCancelled()){
        return "";
    }else{

                MyApplication myApplication = (MyApplication) context.getApplicationContext();
                String IPAddress = myApplication.getIpaddress();
                String domain = myApplication.getDomainname();
                String username = myApplication.getUsername();
                String password = myApplication.getPassword();
                String containingFolder = myApplication.getSharefolder();
                String temp = "";

                //return null;

                if (strings[1].equals("delay")) {
                    try {
                        Thread.sleep(6000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (strings[0].equals("CheckDatabase")) {
                    temp = checkDatabaseConnect();
                } else {
                    temp = checkImageConnection(IPAddress, domain, username, password, containingFolder);
                }
                return temp;
            }


    }

String checkDatabaseConnect() {
    String statement = "PRAGMA sync_status";
    JSONArray is_ready = new JSONArray();
    try {
        SQLiteStatement mystatement = null;

        try {
            mystatement = sqLiteConnection.prepareStatement(statement);
        } catch (SQLException ex) {
            try {

                java.io.File path = new java.io.File("/sdcard/exports/logs");
                SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
                String currentDateTime = dateFormat.format(new Date()) + " ";
                java.io.File myFile = new java.io.File(path, "DBCrashes.txt");
                FileOutputStream fOut = new FileOutputStream(myFile, true);
                OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
                myOutWriter.append("\n" +
                        "\r");
                myOutWriter.append(currentDateTime + "Get pragma results: (" + statement + ")" + ex);
                myOutWriter.close();
                fOut.close();
            } catch (java.io.IOException e) {
                //do something if an IOException occurs.
            }

        }
        mystatement.step();
        int ncols = mystatement.getColumnCount();

        if (ncols > 0) {
            String result = mystatement.getColumnTextNativeString(0);
            JSONObject jObject = new JSONObject(result);
            is_ready = jObject.getJSONArray("peers");
            if (is_ready.length() > 0) {
                return "Success, Database is connected! (1)";
            } else {
                return "The database is not connected to the server. In offline mode, check network and restart application to connect to server. (0)";

            }
        }
        mystatement.dispose();

    } catch (SQLException ex) {
        try {

            java.io.File path = new java.io.File("/sdcard/exports/logs");
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
            String currentDateTime = dateFormat.format(new Date()) + " ";
            java.io.File myFile = new java.io.File(path, "DBCrashes.txt");
            FileOutputStream fOut = new FileOutputStream(myFile, true);
            OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
            myOutWriter.append("\n" +
                    "\r");
            myOutWriter.append(currentDateTime + " (" + statement + ")" + ex);
            myOutWriter.close();
            fOut.close();
            return "No connection to a database, please try again (2)";
        } catch (java.io.IOException e) {

            //do something if an IOException occurs.

        }

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

    return "Success (5)";

}
}

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

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

попробуйте проверить, отменяется ли задание после Thread.sleep(6000), поэтому, даже если задание находилось в спящем режиме при вызове отмены, оно вернется после завершения.

if (strings[1].equals("delay")) {
   try {
      Thread.sleep(6000);
      if(this.isCancelled()) {
          return "";
      }
   } catch (InterruptedException e) {
      e.printStackTrace();
   }
   /*if(this.isCancelled()) {
      return "";
   }*/
}
0 голосов
/ 10 февраля 2019

Вы реализовали обработку для isCanceled, но эта реализация только в начале.

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

  1. задача запускается, немедленно проверяет, отменена она или нет (так как это первая строка в doInBackground)
  2. onPauseвызывается, отменяется задача
  3. , поскольку проверка отмены уже выполнена, ваша задача продолжает выполняться свободно

Как вы решаете эту проблему?

Самый простой способ - проверить, отменено ли оно, перед вызовом checkDatabaseConnection или checkImageConnection.И даже внутри этих методов проверьте, отменен ли он или нет.

Даже если это сделано правильно, ваш Thread.sleep может вызвать отмену AsyncTask через 6 секунд после вызова onPause.

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

Этот или даст вам отправную точку.

...