2016-01-20 3 views
0

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

Интерфейс

interface getData { 
    void done (ArrayList<String> returnedData); 
} 

AsyncTask и вызова метода с помощью класса-оболочки под названием serverRequests

public void getDataInBackground (String params, getData retData){ 
    new getDataAsync(params,retData).execute(); 
} 
public class getDataAsync extends AsyncTask<Void,Void,ArrayList<String>> { 
    String params; 
    getData retData; 
    public getDataAsync(String params, getData retData){ 
     this.params=params; 
     this.retData=retData; 
    } 
    @Override 
    protected ArrayList<String> doInBackground(Void... params) { 
     ArrayList<String> list = new ArrayList<>(); 
     //Do a bunch of stuff that connects to my server 
     return list; 
    } 
    @Override 
    protected void onPostExecute(ArrayList<String> returnedData) { 
     retData.done(returnedData); 
     super.onPostExecute(returnedData); 
    } 
} 

Тогда моя активность класса, который называет этот процесс будет вот так.

public class MyActivity extends AppCompatActivity { 
    ServerRequests serverRequests; // the Wrapper class to call my different AsyncTasks 
    ArrayList<String> someList; 
    String params="some kind of params"; 

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

    serverRequests= new serverRequests(this);//this being the context passed 
    someList=new ArrayList<>(); 

    serverRequests.getDataInBackground(params, new getData() { 
     @Override 
     public void done(ArrayList<String> returnedData) { 
      someList.addAll(returnedData); 
      //somelist has data here 
      //used AlertDialogs to confirm data 
     } 
    }); 
    //someList is empty here and data is needed to perform other tasks. 
    // again used AlertDialogs to confirm data 

В настоящее время я выполняю несколько других сборок AsyncTasks для конечного пользователя. Другие данные задачи зависят от этого первого вызова. Я подумал о временном хранении данных на телефоне, а затем подумал о моей жене, чей телефон всегда ограничен в пространстве памяти, что может вызвать нежелательную ошибку. Я думал о выполнении другой AsyncTask внутри этого, но тогда я бы разворачивал несколько потоков без необходимости и тратил процессор на телефон. Я пробовал другие предложения, которые я нашел на этом сайте, например, сделать static/final someList, но это тоже не работает. Я также попробовал просто простое назначение someList = returnData. Итак, любые предложения о том, как получить это значение от AsyncTask и в вызывающем методе?

ответ

0

Его вполне приемлемый вариант для запуска второй AsyncTask в onPostExecute первого, если второй зависит от результата первого. Вы действительно не должны беспокоиться о нескольких потоках - в первую очередь AsyncTasks находятся в очереди в одном потоке, если вы явно не запрашиваете иное. Во-вторых, ваши задачи, вероятно, связаны с IO. В-третьих, использование ЦП - это небольшое количество потребления батареи по сравнению с такими вещами, как GPS и дисплей - вам в значительной степени нужно попытаться сделать вмятину с ним.

+0

хорошо это первый из 5 задач, которые будут использоваться результаты первого в следующем, чтобы создать пользовательский ArrayAdatper с фрагментированным макетом ListView. Итак, запустить 5 вложенных потоков приемлемо для android? Я имею в виду, если бы ваш facebook не думал, что мы сможем сгореть чей-то карман, нагрев телефон. – jmodine

+0

Если вы хотите подключиться к сетевым запросам, вы все равно не будете сжигать CPU - вы будете блокировать IO.Если бы я был вами, я был бы больше обеспокоен тем, что он так долго должен был получить результат, чем я использовал бы процессор. Считаете ли вы создание более мощного API, который может выполнять большую часть работы на сервере, чтобы сократить его до 1-2 вызовов? –

+0

Я думал о том, что, вероятно, так мне нужно идти, если я не могу получить значение вне onPostExetute. Я боюсь, что это означает, что день работы воссоздает webInterface, а затем воссоздает Custom Adapter. Таким образом, вы не знаете, как получить это значение для вызывающего класса, не используя поток пользовательского интерфейса, который другие предложили? – jmodine

0

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

protected void setValue(ArrayList<String> list){ 
    this.someList=list;} 

тогда в моей первоначальной деятельности класса, где я имел

someList.addAll(returnedData); 

я заменил его

setValue(returnedData); 

Таким образом, делая значение доступным в течение целого класса

1

интерфейс за работой.

//access download task data 
public interface MyAccessResponse { 
    void postResult(String asyncResult); 
} 

//download class 
public class DownloadTask extends AsyncTask<String, Void, String> { 


    public MyAccessResponse delegate=null; 
    public DownloadTask(MyAccessResponse asyncResponse) { 
     delegate = asyncResponse;//Assigning call back interfacethrough constructor 
    } 


    @Override 
    protected String doInBackground(String... urls) { 

     URL url; 
     HttpURLConnection urlConnection = null; 

     try { 
      //read 1st string 
      url = new URL(urls[0]); 
      urlConnection = (HttpURLConnection) url.openConnection(); 

      InputStream inpt = urlConnection.getInputStream(); 

      BufferedReader reader = new BufferedReader(new InputStreamReader(inpt)); 
      StringBuilder builder = new StringBuilder(); 
      String aux = ""; 

      while ((aux = reader.readLine()) != null) { 
       builder.append(aux); 
      } 
      return builder.toString(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 


    @Override 
    protected void onPostExecute(String result) { 

     Log.i("tms delegate", "access delegate"); 

     //super.onPostExecute(result); 
     if(result!=null && delegate!=null) 
     { 
      delegate.postResult(result); 
     } else { 
      Log.i("MyAccess", "You have not assigned IApiAccessResponse delegate"); 
     } 
    } 
} //end of Download Task 

В OnCreate: ...

DownloadTask task = new DownloadTask(new MyAccessResponse() { 

     @Override 
     public void postResult(String asyncResult) { 
      //html = asyncResult ; 
      //Log.i("tms postResult", html); 
      //process result--split point: "/imgs/hr_shadow.gif" 
      String[] splitResult = asyncResult.split("/imgs/hr_shadow.gif"); 

      //example: <img src="/celebs/rihanna/thumbs/thumb1.jpg" alt="Rihanna" height="95" width="95" border="0" /> 
      Pattern p = Pattern.compile("src=\"(.*?)\""); 
      Matcher m = p.matcher(splitResult[1]); 
      while(m.find()) { 
       celebURLs.add(m.group(1)); 
       Log.i("tms src:", m.group(1)); 
      } 

      p = Pattern.compile("alt=\"(.*?)\""); 
      m = p.matcher(splitResult[1]); 
      while(m.find()) { 
       celebNames.add(m.group(1)); 
       Log.i("tms name:", m.group(1)); 
      } 

      createNewQuestion(); 
     } 
    }); 
+0

Предложение: используйте Volley или OkHttp вместо этого –

Смежные вопросы