简体   繁体   中英

Execute AsyncTask in Fragment from another Activity class and update UI inside it

I'm trying to execute AsyncTask from a fragment class (eg MyFragment.java) from another Activity class (eg MyActivity.java) .

the fragment class MyFragment.java is updating UI on it's elements:

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;
        }
    }
}

I'm trying to Execute AsyncTask from MyActivity.java

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

The Application crashes at onPreExecute :

java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.swiperefreshlayout.widget.SwipeRefreshLayout. setRefreshing(boolean) ' on a null object reference.

I'm assuming this is because it couldn't access myRefreshLayout to perform setRefreshing(true) on it, because i'm running the task from another thread MyActivity.java

How can i execute the AsyncTask on the Fragment .. from the Activity and change the UI?

Thanks.

Idk if this would be a nice solution. But I think you can make MainActivity implements this custom interface. It'd be a callback that should be execute after the swipe action done.

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);
}

in your fragment

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM