In my Android application, I have a fragment activity which it has a progressbar. This progress bar set to visible when any fragment invoke the interface. Therefore, the code for fragment class is like this:
public class MainScreen extends FragmentActivity {
public interface OnConnectingToInternet {
public void showProgressbar(boolean flag);
}
// rest of codes
.
.
.
// Implementing Interface
public void showProgressbar(boolean flag) {
if(flag){
myProgressbar.showProgressBar();
} else {
myProgressbar.hideProgressBar();
}
}
}
Each fragment should connect to Internet and get data, however before that they should invoke interface. I have written following code for one class (the code for other fragments is like this).
public class TopRecipesFragment extends Fragment {
private OnConnectingToInternet onConnectingToInternet;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// onConnectingToInternet = (OnConnectingToInternet) activity;
Log.i(TAG, "Fragment attached to activity.");
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
New MyAsyncTask.execute();
}
public class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected void onPreExecute() {
Log.i(TAG, "myAsyncTask is about to start...");
onConnectingToInternet.showProgressbar(true);
}
@Override
protected Boolean doInBackground(Void... params) {
...
}
@Override
protected void onPostExecute(Boolean result) {
Log.i(TAG, "myAsyncTask is about to start...");
onConnectingToInternet.showProgressbar(false);
}
}
The problem is I don't know how to instantiate this interface. If I don't put onConnectingToInternet = (OnConnectingToInternet) activity;
, then, after running application, it will crash in a NullPointerException
.
But, if I instantiate like that, then application crashes because of casting problem. I cannot instantiate it in normal way either, like onConnectingToInternet = new MainScreen();
.
What is the solution? Any suggestion would be appreciated. Thanks
The problem is that sometimes a Fragment lives longer than its Activity, for example, if the Activity has a config change (e.g. rotated) then the Activity is destroyed, but the Fragment can be kept alive and then reattached to the new (rotated) Activity. See this post: Android Fragment lifecycle over orientation changes
So you might have a problem with the proposed solution using the WeakReference, because after a rotation you would have a reference to the old Activity (or maybe nothing).
Though I’m not sure why the line crashed in onAttach(), that should have been ok.
What seems to work for me:
1) When I need a ref to the Activity, call getActivity(). Do this right in onPostExecute().
2) Check the result for null (this can happen: Fragments can live longer than their Activities)
3) Check if activity isFinishing() – you don’t want to do certain UI things in that state.
4) Cast activity to your interface type.
5) Call showProgressBar().
I would write that You're trying to do the following way:
OnConnectingToInternet.java:
MainScreen.java:
TopRecipesFragment.java: