I have a tab fragment inside of a container activity.
I would like to download some data to display in the tab. In the tab, I have made an asynctask that I execute just after inflating the fragment layout in onCreateView. When I do it this way, the AsyncTask's doInBackground... work occurs on the main thread and the view does not load until it is done. All of my progress... logs show up at the same time as soon as the task is done.
However, if I put a button in the fragment layout and start the asynctask work as a response to the button click, it works as expected, I get my normally spaced progress updates.
So, why does AsyncTask run on the main thread if it is the first thing to happen when my fragment starts? And, how can I prevent this? My ultimate goal is to show a progress wheel while the data is downloading.
Edit. Here is where I call my AsyncTask.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.temp_my_moments, container, false);
getMyClips(getActivity(), rootView, p_session, p_person,progressBar);
//If I use this button, it works fine:
// test = (Button) rootView.findViewById(R.id.testbutton);
// test.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// progressBar =(ProgressBar) rootView.findViewById(R.id.myMomentsProgress);
// getMyClips(getActivity(), rootView, p_session, p_person, progressBar);
// }
// });
return rootView;
}
And here is getMyClips():
public void getMyClips(Context context,View view,String thisSession,String thisPerson,ProgressBar progressBar) {
Log.d("Currently running", "getMyClips");
JSONObject params = new JSONObject();
try {
params.put("Function", clipsMine_apiCall);
params.put("p_session", thisSession);
params.put("p_person", thisPerson);
} catch (JSONException e1) {
e1.printStackTrace();
}
ApiClipCaller webServiceTask = new ApiClipCaller(context,view,progressBar);
if (webServiceTask.hasConnection()) {
webServiceTask.execute(params);
} else {
//TODO no internet connection
}
}
Edit Here is my AsyncTask. This is inside the Fragment:
public class ApiClipCaller extends AsyncTask<JSONObject, Integer, ApiResponse> {
public Context context;
public String clipID;
public String sessionID;
public String personID;
public String functionName;
public View view;
public ProgressBar progressBar;
public final String apiURL = "...."; //need to keep private
LinearLayout loading;
public ApiClipCaller(Context c, View v,ProgressBar progressBar) {
this.context = c;
this.view = v;
this.progressBar = progressBar;
loading = (LinearLayout) view.findViewById(R.id.loadingMyMoments);
}
@Override
protected ApiResponse doInBackground(JSONObject... params) {
JSONObject realParams = params[0];
try {
functionName = realParams.getString("Function");
} catch (JSONException e) {
e.printStackTrace();
}
ApiResponse responseObject = masterFunction(realParams);
//making some work to see if it is running correctly
for (int i=10;i<=100;i += 10)
{
try {
Thread.sleep(1000);
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return responseObject;
}
@Override
protected void onProgressUpdate(Integer... progress) {
loading.setVisibility(View.VISIBLE);
progressBar.setProgress(progress[0]);
Log.d("progress",Integer.toString(progress[0]));
}
@Override
protected void onPostExecute(ApiResponse responseObject) {
loading.setVisibility(View.GONE);
if (functionName.equals(clipsMine_apiCall)) {
JSONObject clipObject = responseObject.getResponseJSONObject();
//just testing here to see if I can get data back in the fragment view when it is done.
///This works as expected.
String responseString = responseObject.getResponseString();
TextView showAsyncResults = (TextView) view.findViewById(R.id.testAsyncTask);
showAsyncResults.setText(responseString);
}
super.onPostExecute(responseObject);
}
}