1

Рассказ:
Мне нужно переместить немного кода из моего потока пользовательского интерфейса и в фоновый поток, и мне нужно иметь возможность передавать пять значений переменных в этот фоновый поток и получать от него пять значений , Я надеюсь, что кто-то может предоставить простой рабочий пример, притворившись, что код ниже - мой код, а бит между комментариями - это то, что нужно переместить.

Longer история:
Часть кода в моем UI потоке занимает около пятнадцати секунд, чтобы закончить. Экран замерзает в течение этого периода. Я не против, что экран зависает, потому что пользователю в любом случае не нужно взаимодействовать с экраном. Проблема в том, что у меня также есть OnKeyListener в моем потоке пользовательского интерфейса, и он не одобряет задержку. Если пользователь нажимает любую клавишу клавиатуры во время пятнадцатисекундной задержки, это приведет к появлению приглашения ANR (приложение не отвечает) примерно через пять секунд. Мне нужно переместить трудоемкий код в отдельный поток, где он может работать в фоновом режиме. Я потратил около 13 часов, пытаясь понять, как это сделать, используя AsyncTask и другие методы, но не смог понять, как передать пять значений переменных в поток и получить от него пять значений. Я надеюсь, что кто-то может предоставить простой рабочий пример, притворившись, что код ниже - мой код, а бит между комментариями - это то, что нужно переместить.Android - Как передать пять значений переменных в фоновый поток и получить пять значений от него?

 myButton.setOnClickListener(new OnClickListener() 
     { 
      public void onClick(View arg0) 
      { 
      Integer userNum1 = 12; //pretend these numbers are user inputted (ever-changing) 
      Integer userNum2 = 8; 
      Integer userNum3 = 2; 
      Integer userNum4 = 31; 
      Integer userNum5 = 17; 
      Integer userMultiplier = 9; 
      //----------------------------- 
      for (int i = 0; i < 15; i++) 
      { 
      userNum1 = userNum1 * userMultiplier; 
      userNum2 = userNum2 * userMultiplier; 
      userNum3 = userNum3 * userMultiplier; 
      userNum4 = userNum4 * userMultiplier; 
      userNum5 = userNum5 * userMultiplier; 

      try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} 
      } 
      //----------------------------- 
      String myString1 = String.valueOf(userNum1); 
      String myString2 = String.valueOf(userNum2); 
      String myString3 = String.valueOf(userNum3); 
      String myString4 = String.valueOf(userNum4); 
      String myString5 = String.valueOf(userNum5); 
      } 
     }); 



EDIT:
Вот что я в конечном итоге делает, чтобы решить эту проблему:

public Integer myTaskDone = 0; 
public Integer userNum1 = 0;  
public Integer userNum2 = 0;  
public Integer userNum3 = 0;  
public Integer userNum4 = 0;  
public Integer userNum5 = 0; 
public Integer userMultiplier = 0; 
public String[] valueTransporter = new String[20]; 





myButton.setOnClickListener(new OnClickListener() 
{ 
    public void onClick(View arg0) 
    { 
    userNum1 = 12; 
    userNum2 = 8; 
    userNum3 = 2; 
    userNum4 = 31; 
    userNum5 = 17; 
    userMultiplier = 9; 

    valueTransporter[0] = String.valueOf(userNum1); 
    valueTransporter[1] = String.valueOf(userNum2); 
    valueTransporter[2] = String.valueOf(userNum3); 
    valueTransporter[3] = String.valueOf(userNum4); 
    valueTransporter[4] = String.valueOf(userNum5); 
    valueTransporter[5] = String.valueOf(userMultiplier); 

    new myTask().execute(valueTransporter); 
    } 
}); 





//Had to move the last section of code into this new thread, otherwise the code would have executed before myTask finished. 
//All this thread does is frequently check myTaskDone to see if it equals 1 (if it does equal 1, the last section of code will be executed). 
final Handler mHandler = new Handler(); 
new Thread(new Runnable() 
{ 
@Override 
    public void run() 
    { 
     while (true) 
     { 
     try 
     { 
     Thread.sleep(10); 
      mHandler.post(new Runnable() 
      { 
      @Override 
       public void run() 
       { 
        if (myTaskDone == 1) 
        { 
        myTaskDone = 0; 
        String myString1 = String.valueOf(userNum1); 
        String myString2 = String.valueOf(userNum2); 
        String myString3 = String.valueOf(userNum3); 
        String myString4 = String.valueOf(userNum4); 
        String myString5 = String.valueOf(userNum5); 
        } 
       } 
      }); 
     } catch (Exception e) {} 
     } 
    } 
}).start(); 




public class myTask extends AsyncTask<String,String,String[]> 
{ 
    @Override 

    protected String[] doInBackground(String... valueTransporter) 
    { 

    //Our values have been transported in via valueTransporter. Put those values back into variables so we can work on them.  
    Integer userNum1 = Integer.parseInt(valueTransporter[0]); 
    Integer userNum2 = Integer.parseInt(valueTransporter[1]); 
    Integer userNum3 = Integer.parseInt(valueTransporter[2]); 
    Integer userNum4 = Integer.parseInt(valueTransporter[3]); 
    Integer userNum5 = Integer.parseInt(valueTransporter[4]); 
    Integer userMultiplier = Integer.parseInt(valueTransporter[5]); 

     //Do work 
     //----------------------------- 
     for (int i = 0; i < 15; i++) 
     { 
     userNum1 = userNum1 * userMultiplier; 
     userNum2 = userNum2 * userMultiplier; 
     userNum3 = userNum3 * userMultiplier; 
     userNum4 = userNum4 * userMultiplier; 
     userNum5 = userNum5 * userMultiplier; 

     try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} 
     } 
     //----------------------------- 

    //Now that the work has been done on the values, load them back into valueTransporter. 
    valueTransporter[0] = String.valueOf(userNum1); 
    valueTransporter[1] = String.valueOf(userNum2); 
    valueTransporter[2] = String.valueOf(userNum3); 
    valueTransporter[3] = String.valueOf(userNum4); 
    valueTransporter[4] = String.valueOf(userNum5); 

    return valueTransporter; 
    } 

    protected void onPostExecute(String[] valueTransporter) 
    { 
    //Get the values out of valueTransporter and into the original variables used by the UI thread. 
    userNum1 = Integer.parseInt(valueTransporter[0]); 
    userNum2 = Integer.parseInt(valueTransporter[1]); 
    userNum3 = Integer.parseInt(valueTransporter[2]); 
    userNum4 = Integer.parseInt(valueTransporter[3]); 
    userNum5 = Integer.parseInt(valueTransporter[4]); 

    myTaskDone = 1; 
    } 

} 
+2

вы можете передать значения конструктору asynctask, и для возврата вы можете проверить это http://stackoverflow.com/questions/16752073/how-do-return-a-boolean-from-asynctask – Raghunandan

+0

@ Raghunandan : Я вижу способ, которым я могу передать пять значений в фоновый поток, но я не вижу, как я могу получить от него пять значений. –

+0

Вы проверили ссылку выше, используя метод интерфейса, предложенный в принятом ответе – Raghunandan

ответ

0

Вы можете очистить это, помещая выходы MyTask:

  • создать поле для каждого выходного значения на MyTask
  • устанавливать свои значения в onPostExecute()
  • изменения 'булево myTaskDone' к 'MyTask finishedTask'
  • изменения 'myTaskDone = 1' до 'finishedTask = это'
  • изменения 'если (myTaskDone == 1)' до 'если (finishedTask! = NULL)'

Тогда вы можете просто вытащить значения от объекта задачи, и вы можете удалить valueTransporter.

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