2016-04-07 2 views
0

У меня есть данные JSON, которые я преобразовал в JSONArray. Я выполнил это преобразование во внутреннем классе, который распространяется AsyncTask.Как передать данные из класса Async в основной класс активности

Теперь у меня есть данные, которые содержат Images и их Titles. Я хочу создать Loop и создать ImageView динамически.

Проблема, с которой я столкнулся, заключается в том, что мои данные находятся во внутреннем классе и в методе doInBackground(), и все это; i.e: ImageView Мне нужно создать в классе Outer и в методе onCreate().

Я не могу понять, как использовать jsonArray, который я создал в своем InnerClass в моем внешнем классе.

Внутренний класс:

общественного класса NewsService расширяет AsyncTask {

@Override 
    protected JSONArray doInBackground(String... params) { 

     URL url = null; 
     try { 
      //All JSON to JSONArray conversion code goes here 
      //.. 

      JSONArray jsonArray = new JSONArray(jsonString); 
     return jsonArray; 

Основная деятельность

public class MainActivity extends Activity { 

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

     NewsService newsService = new NewsService(); 
     newsService.execute(); 

//I need to use `jsonArray` in this part of my code 
+0

Вы хотите передать JSONArray возвращаемого doInBackground в MainActivity? –

+0

Это может вам помочь: http://stackoverflow.com/questions/14827532/waiting-till-the-async-task-finish-its-work – Pablo

+0

Вы не можете использовать jsonArray в этой части кода. Вы должны использовать его в onPostExecute, а не –

ответ

2

Один простой способ сделать это определяя interface как ваш AsyncTask обратный вызов. Вот пример:

public interface Callback { 
    void processData(DataType data); 
} 

и в вашем MainActivity вы должны implement что interface:

public class MainActivity extends Activity implements Callback { 
    ... 
    void processData(DataType data) { 
    //your code here 
    } 
} 

и в коде вызова:

new NewService(this).execute(); 

и ваш NewService класс:

public class NewService extends AsyncTask ... { 
    ... 
    Callback cb; 
    public NewService(Callback cb) { 
    this.cb = cb; 
    } 
    ... 
} 

и вызвать ваш Callback метод onPostExecute

void onPostExecute(DataType data) { 
    cb(data); 
} 
+0

. Конечно, лучше использовать 'WeakReference' для вашего экземпляра' Callback' в вашем классе 'AsyncTask'. –

+0

этот метод обратного вызова работает и для меня также –

+0

Не делайте задачу async внутренним классом, а статическим внутренним классом. Это отделит задачу от пользовательского интерфейса, и вы предотвратите утечку памяти из-за возможных изменений конфигурации (экран вращается, пользователь меняет язык и т. Д.). Затем эта задача может быть отправлена ​​обратно с помощью системы обратного вызова. – Ryan

4

У меня есть ряд решений для вашей проблемы.

  1. На вершине, что приходит мне в голову, что вы передаете контекст класса деятельности в качестве члена данных вашего асинхронном класса задач, а затем, когда работа donein onPostExecute

    ((YourActivityName) контекста).createDynamicImages (yourJsonArray);

Перед этим необходимо сохранить контекст вашей деятельности в качестве члена данных асинхронного класса задач

YourAsyncTask task = new YourAsyncTask(this); 
task.execute(); 

и поэтому конструктор вашего асинхронного класса задач станут

public YourAsyncTask(Context context){ 
    this.context = context; 
} 
0

AsynTask.doInBackground работает на Фон, Не на основной теме, так что вы ульд использовать onPostExecute(этот метод выполняется после выполнения задачи) в случае, если вы хотите данные процесса на главном потоке, включая обновление пользовательского интерфейса, можно добиться того, что с помощью interface внутри AsyncTask класса:

interface OnJsonArrayReceive { 
    void onReceive(JSONArray array); 
    } 

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

class SomeTask extends AsyncTask<String, Void, JSONArray> { 

    OnJsonArrayReceive mOnJsonArrayRecieve; 

    public SomeTask(OnJsonArrayRecieve listener) { 
     mOnJsonArrayRecieve = listener; 
    } 

    @Override 
    protected JSONArray doInBackground(String... params) { 
     //do something with and return your array 
     //this runs on background 
     return jsonArray; 
    } 

    @Override 
    protected void onPostExecute(JSONArray jsonArray) { 
     //This runs on main thread 
     if (mOnJsonArrayReceive != null) { 
      mOnJsonArrayReceive.onReceive(jsonArray); 
     } 
    } 
} 

Этот класс принимает OnJsonArrayRecieve слушателя в качестве аргумента (который реализуется в MainActivity) и когда данные процесс на фоне сделано onRecieve будет называться, использовать его в вашем коде, как это:

new SomeTask(new OnJsonArrayRecieve() { 
     @Override 
     public void onReceive(JSONArray array) { 
      //do something with json array 
     } 
     }).execute(someArgument); 
Смежные вопросы