#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!