Выполнить AsyncTask во фрагменте из другого класса Activity и обновить пользовательский интерфейс внутри него

#java #android #android-fragments #android-asynctask

#java #Android #android-фрагменты #android-asynctask

Вопрос:

Я пытаюсь выполнить AsyncTask из класса fragment (e.g MyFragment.java) из другого класса Activity (e.g MyActivity.java) .

класс fragment MyFragment.java обновляет пользовательский интерфейс для своих элементов :

 public class MyFragment extends Fragment {

    private SwipeRefreshLayout myRefreshLayout;
    private ArrayAdapter myListAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        myListAdapter = new myCustomAdapter(getContext(), myDataArray);
        myRefreshLayout = myView.findViewById(R.id.myRefreshLayout);
    }

    public class MyTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            // UI...
            myRefreshLayout.setRefreshing(true);
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            // UI...
            myRefreshLayout.setRefreshing(false);
            myListAdapter.notifyDataSetChanged();
        }

         @Override
        protected Void doInBackground(Void... params) {

            // code...
            return null;
        }
    }
}
  

Я пытаюсь выполнить AsyncTask из MyActivity.java

 MyFragment myfragment = new MyFragment();
myfragment.new MyTask.execute();
  

Приложение вылетает при onPreExecute :

java.lang.Исключение NullPointerException: попытка вызвать виртуальный метод ‘void androidx.swiperefreshlayout.виджет.SwipeRefreshLayout.setRefreshing(boolean)‘ для нулевой ссылки на объект.

Я предполагаю, что это связано с тем, что он не смог получить доступ myRefreshLayout к нему для выполнения setRefreshing(true) , потому что я запускаю задачу из другого потока MyActivity.java

Как я могу выполнить AsyncTask для фрагмента .. из Activity и изменить пользовательский интерфейс?

Спасибо.

Ответ №1:

Idk, если это было бы хорошим решением. Но я думаю, вы можете сделать MainActivity реализует этот пользовательский интерфейс. Это будет обратный вызов, который должен быть выполнен после выполнения действия салфетки.

 public class MainActivity extends AppCompatActivity implements MyAsyncCallback {
    ....
    ....

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

        MyFragment myfragment = new MyFragment();
        myfragment.new MyTask(this).execute();
    }

    @Override
    public void onPreExecute(Boolean isRefreshing) {
        if(isRefreshing){
            // UPDATE MAIN UI
        }
    }
 
    @Override
    public void onPostExecute(Boolean isRefreshing) {
       if(isRefreshing){
            // UPDATE MAIN UI
        }
     }
}

interface MyAsyncCallback {
    void onPreExecute(Boolean isRefreshing);
    void onPostExecute(Boolean isRefreshing);
}
  

в вашем фрагменте

 public class MyTask extends AsyncTask<Void, Void, Void> {
    WeakReference<MyAsyncCallback> myListener;

    public MyTask(MyAsyncCallback listener){
        this.myListener = listener
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
    Bundle savedInstanceState) {
       // don't forget to return view
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        
        MyAsyncCallback myListener = this.myListener.get();
        if (myListener != null) {
            myListener.onPreExecute(true);
        }

        myRefreshLayout.setRefreshing(true);
    }

    //same for onPostExecute()
  

Комментарии:

1. Проблема заключается в обновлении элементов пользовательского интерфейса во фрагменте, а не в mainactivity, как я уже говорил, когда вызывал AsyncTask из mainactivity .. элементы пользовательского интерфейса во фрагменте выдают ошибку, поскольку они будут недоступны для обновления, когда вызов поступает извне фрагмента. я описал это the fragment class MyFragment.java is updating UI on it's elements : .. вы предоставили очень хороший пример использования обратного вызова asynctask, который может помочь в других случаях! спасибо maftu!