#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_home, container, false);
return myFragmentView;
}
I normally have this onCreateView executing and all my code was in it, due to a recommendation I took and inserted the remainder of my code into onViewCreated. I am not complaining but the exact same thing happened. The ASyncTask doesn't execute as I open the fragment activity. Here's my onViewCreated :
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
Requ connReq = new Requ();
connReq.execute(); //go go power rangers
}
It's not that complicated after all but for some reason it doesn't launch my asynctask. It 'shows' the ProgressDialog which begins in onPreExecute and dismisses in onPostExecute. So you could say that it just won't execute my doInBackground What am I doing wrong with this thing? I just want my ASyncTask to execute as I open the fragment and load my data.
I'd really appreciate the help, thanks in advance. I searched all over the place but I really couldn't find a proper solution for this, I thought there'd be one.
PS: the asynctask works just well when I add the execution to an onClickListener
my asynctask:
private class Requ extends AsyncTask<String, String[], String[]> {
final String pdMessage = getString(R.string.pd_wait);
ProgressDialog pd = new ProgressDialog(getActivity());
#Override
protected void onPreExecute () {
pd.setMessage(pdMessage);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setCancelable(false);
pd.setIndeterminate(true);
pd.show();
}
#Override
protected String[] doInBackground(String... params) {
String[] connResult;
final String SipUrlStr = getString(R.string.sip_url);
String bsm = "";
String bst= "";
String hs= "";
String as= "";
try {
JSONTokener SipTokener = new JSONTokener(Sources.httpConnGet(SipUrlStr).toString());
JSONArray SipArray=new JSONArray(SipTokener);
for(int i=0; i<(SipArray.length()); i++)
{
JSONObject json_obj_sip = yeniSipArray.getJSONObject(i);
bsm = json_obj_sip.getString("mt");
bst = json_obj_sip.getString("tt");
hs = json_obj_sip.getString("pta");
as = json_obj_sip.getString("pta2");
}
} catch (Exception e) {
bsm = getString(R.string.def_sip);
bst = getString(R.string.def_sip);
hs = getString(R.string.has);
as = getString(R.string.ass);
}
connRes = new String[]{bsm, bst, hs, as};
return connRes;
}
#Override
protected void onPostExecute(String[] connRes) {
super.onPostExecute(connRes);
res[0] = connRes[0];
res[1] = connRes[1];
res[2] = connRes[2];
res[3] = connRes[3];
res[4] = connRes[4];
res[5] = connRes[5];
res[6] = connRes[6];
res[7] = connRes[7];
res[8] = connRes[8];
res[9] = connRes[9];
res[10] = connRes[10];
res[11] = connRes[11];
pd.dismiss();
}
}
Try starting your async task in
onActivityCreated
Function
public void onActivityCreated(Bundle b){
super.onActivityCreated(b);
// Execute here
//Get views
getView().findViewById(<ID>);
}
As it turns out it was about the cycle. Since I was trying to launch AsyncTask on MainThread the code flew by and AsyncTask didn't have enough time to finish its job. And one absolutely shouldn't make the thread wait for AsyncTask. It's against the first rule of AsyncTask. 'not doing that.' Okay, so I moved the execution of AsyncTask to onCreate() that way it will have more time and it won't execute everytime I open the fragment...
#Override
public void onCreate(Bundle savedInstanceState) {
Requ connReq = new Requ();
connReq.execute(); //go go power rangers
super.onCreate(savedInstanceState);
}
then, this is important, I moved all my code into onPostExecute() method of AsyncTask. If you want to change a variable or change a view you should just do it onPostExecute().
Related
I don't understand where is my error. I have a Fragment and on onCreateView I creat and execute an AsyncTask. but it shows no results.
My fragment
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.thread_layout, container, false);
TextView tv = (TextView) view.findViewById(R.id.textView1);
ThreadAsyncTask threads = new ThreadAsyncTask(addressOfThread);
threads.execute();
tv.setText(threads.getResulf());
return view;
}
}
and my AsyncTask
public class ThreadAsyncTask extends AsyncTask<String, Void, String> {
private String addressOfThread = "";
public String resulf = "aaaa";
public ThreadAsyncTask(String url) {
this.addressOfThread = url;
}
public String getResulf(){
return new String(this.result);
}
}
You must override doInBackground method to get/handling your data.
This data is available in onPostExecute method and from here, call back it to your UI (Activity or Fragment).
Please see my example gits to understand this process:
AsyncTask: https://gist.github.com/hongthaiis/77a847d2011f627c2c60#file-getweatherdatatask-java
Activity with call back method: https://gist.github.com/hongthaiis/43477678bb2764cfc0f6#file-weatheractivity-java
Hope this help! :D
you need to implement doInBackground method, in this method you need to specify the operations you want the task to execute in a separate thread.
After this if you need to modify the UI with the result you obtained from doInBaackground, you have to implement the metod onPostExecute.
I have a fragment activity. When i click the fragment it fires a listener which fires an AsyncTask. I need the Async tasks result before moving to the next line of code in the listener i.e i need the asyncTask to be synchronous.
To do this i usually use a dialog to effectively make user wait for asyncTask onPostExecute(). But my dialog isnt appearing and my code is moving on past the asyncTask and into the bundle code which then adds null variables, sad face.
Here is the bones of my fragment class, let me know if you need anything else, i'm conscious of posting too much but i am sure its connected to the structure of my class and fact i'm using fragments.
public class Login_StaggeredGrid_Fragment_Activity extends FragmentActivity
{
private ArrayList<String[]> gameSummaryTilesData;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
final FragmentManager fm = getSupportFragmentManager();
// Create the list fragment and add it as our sole content.
if (fm.findFragmentById(android.R.id.content) == null) {
final StaggeredGridFragment fragment = new StaggeredGridFragment();
fm.beginTransaction().add(android.R.id.content, fragment).commit();
}
}
private class StaggeredGridFragment extends Fragment implements AbsListView.OnScrollListener, AbsListView.OnItemClickListener
{
private StaggeredGridView mGridView;
private boolean mHasRequestedMore;
private TilesAdapter mAdapter;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_sgv, container, false);
}
#Override
public void onActivityCreated(final Bundle savedInstanceState) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
//Encapsulate all within a post cereate from a async task or call a blocking http call
super.onActivityCreated(savedInstanceState);
mGridView = (StaggeredGridView) getView().findViewById(R.id.grid_view);
if (savedInstanceState == null) {
final LayoutInflater layoutInflater = getActivity().getLayoutInflater();
View header = layoutInflater.inflate(R.layout.list_item_header_footer, null);
mGridView.addHeaderView(header);
}
if (mAdapter == null) {
mAdapter = new TilesAdapter(getActivity(), R.id.summary1_value);
}
for (String[] data : loginTilesData) {
mAdapter.add(data); //Add each loginTilesData TileAdapter element to an mAdapter where it will be further broken down and used by the TileAdapter
}
mGridView.setAdapter(mAdapter);
mGridView.setOnScrollListener(this);
mGridView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id)
{
try
{
// Loading Games in Background Thread
new GetGamesSummaryTiles().execute();
}
catch (Exception e)
{
e.printStackTrace();
}
Intent i = new Intent(Login_StaggeredGrid_Fragment_Activity.this, GamesSummary_Fragment_Activity.class);
i.putExtra("gamesSummaryTilesData", gameSummaryTilesData);
startActivity(i);
}
}
/**
* Background Async Task to get data for next activity by making HTTP Request
* */
// Progress Dialog
private ProgressDialog qDialog;
// JSON parser class
JSONParser jParser = new JSONParser();
String url_login ="http://XX.XX.XXX.XX/XXXX.php";
class GetGamesSummaryTiles extends AsyncTask<String, String, String>
{
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute()
{
super.onPreExecute();
qDialog = new ProgressDialog(getBaseContext());
qDialog.setMessage("Please wait...");
qDialog.setIndeterminate(false);
qDialog.setCancelable(false);
qDialog.show();
}
#Override
protected String doInBackground(String... args)
{
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject jsonLogin = jParser.makeHttpRequest(url_login, "GET", params);
pk_http pk_dbComms = new pk_http();
try {
gameSummaryTilesData = pk_dbComms.formatHttpResponse_SummaryTile(jsonLogin);
} catch (JSONException e) {
String test = e.getStackTrace().toString();
e.printStackTrace();
}
return jsonLogin.toString();
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String jsonString)
{
// dismiss the dialog after getting all questions
qDialog.dismiss();
// updating UI from Background Thread
/*runOnUiThread(new Runnable() {
public void run() {
}
});*/
}
}
}
Put the your intent calling code in your onPostExecute method and your problem will be solved
move the below code from onItemClick() to onPostExceute
Intent i = new Intent(Login_StaggeredGrid_Fragment_Activity.this, GamesSummary_Fragment_Activity.class);
i.putExtra("gamesSummaryTilesData", gameSummaryTilesData);
startActivity(i);
put your below code in postExecute() methode of asyncTask...
Intent i = new Intent(Login_StaggeredGrid_Fragment_Activity.this, GamesSummary_Fragment_Activity.class);
i.putExtra("gamesSummaryTilesData", gameSummaryTilesData);
startActivity(i);
my screen when I click on a button is slow to load (because of downloading images? the image files are really small though) so I tried to use AsyncTask to help. The program works, but I moved the image loading to an AsyncTask to see if it would load faster and the app crashes every time. I'm guessing it has to do with the way I have it set up. How would I fix it? Would using a runnable thread be better instead? Thanks!
The class:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// no title
requestWindowFeature(Window.FEATURE_NO_TITLE);
// set full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// inflate listview
setContentView(R.layout.gmg);
**new Load.execute(); // executes AsyncTask**
...
gmgListView = (ListView) findViewById(R.id.gmg_list2);
GMGListViewAdapter adapter = new GMGListViewAdapter(this,
R.layout.gmg_list_row, rowItems);
gmgListView.setAdapter(adapter);
gmgListView.setOnItemClickListener(this);
}
The AsyncTask:
private class Load extends AsyncTask<String, Void, Void> {
private ProgressDialog Dialog = new ProgressDialog(GMGListViewActivity.this);
#Override
protected void onPreExecute() {
Dialog.setMessage("Doing something...");
Dialog.show();
}
#Override
protected Void doInBackground(String... params) {
SparseArray<Spanned> gmgText = null;
Integer[] right = null;
SparseArray<Drawable> appIcon = null;
try {
gmgText = ParseContent.queryGMGText();
right = ParseContent.queryGMGRight();
appIcon = ParseContent.queryDrawable();
} catch (ParseException e) {
e.printStackTrace();
}
// Inflate GMG's rows
rowItems = new ArrayList<GMGRowItem>();
for (int i = 0; i < gmgText.size(); i++) {
GMGRowItem item = new GMGRowItem(appIcon.get(i), gmgText.get(i), right[i]);
rowItems.add(item);
}
return null;
}
protected void onPostExecute(Void unused) {
Dialog.dismiss();
}
}
You need to apply some changes in your code like...
need to set list adapter in onPostExecute method and remove it from onCreate().
After completing background process it will interact with ui thread.
protected void onPostExecute(Void unused) {
Dialog.dismiss();
GMGListViewAdapter adapter = new GMGListViewAdapter(this,
R.layout.gmg_list_row, rowItems);
gmgListView.setAdapter(adapter);
}
Try this and let me know if you got any isssue.
So I made an AsyncTask class that runs doInBackground() successfully. I have debugged it, and the entire doInBackground() method runs correctly:
public class MyClass extends AsyncTask<String , String , Boolean> {
protected Boolean doInBackground(String... strings)
{
ArrayList<String[]> stories = new ArrayList<String[]>();
...*irrelevant code that works*...
String[][] storiesA = new String[stories.size()][2];
...*irrelevant code that works*...
ArrayList<Integer> displayed = new ArrayList<Integer>();
//calls publishProgress() every 10 seconds with a random String[2] from storiesA
for (int x = 0 ; x < storiesA.length ; x++)
{
if (displayed.size() >= storiesA.length) displayed.clear();
Random gen = new Random();
int rand;
rand = gen.nextInt(storiesA.length);
while (displayed.contains(rand))
{
rand = gen.nextInt(storiesA.length);
}
displayed.add(rand);
publishProgress(storiesA[rand][0] , storiesA[rand][1]);
long t0 , t1;
t0=System.currentTimeMillis();
do
{
t1=System.currentTimeMillis();
} while (t1-t0<10000);
}
return true;
}
}
As you can see, I made it so the onProgressUpdate() parameter should be String..., as in the method in my UI:
protected void onProgressUpdate(String... stories) {
TextView title = (TextView)findViewById(R.id.bulletinBoardTitle);
TextView body = (TextView)findViewById(R.id.bulletinBoardText);
String titleText = stories[0];
String bodyText = stories[1];
title.setText(titleText);
body.setText(bodyText);
}
In case it's relevant, I also defined:
protected void onPostExecute(Boolean result) {
//will never call this method; it is deprecated in this context
TextView title = (TextView)findViewById(R.id.bulletinBoardTitle);
TextView body = (TextView)findViewById(R.id.bulletinBoardText);
title.setText("Refreshing...");
body.setText("Murica!");
}
So the problem is apparent with all the debuggers I've run. While the entire doInBackground() code (executed here:)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.media);
new MyClass().execute();
}
works well and runs fully, when it calls publishProcess() the onProgressUpdate() method never gets run.
I'm a very novice Android programmer, so please keep that in mind if you have any idea what might be the problem here.
Thanks for the help!
I'm trying to run many AsyncTasks to do loadData() on the same WebView. For example, I have 3 threads with 3 contents: "One", "Two", "Three" and a WebView with content "abc". (like the code below)
After 3 tasks finished, I want the WebView has content: "abcOneTwoThree". The idea of this code is that three threads will append its content to WebView at anytime, so the result could be "abcTwoOneThree" or "abcTwoThreeOne", etc ...
I read many concurrency articles but still don't understand how to implement this. This is my code. It just prints "abcThree".
public class UsingSameWebViewActivity extends Activity implements OnClickListener {
private Button button1;
private WebView webView;
private String result;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(this);
webView = (WebView)findViewById(R.id.webView1);
result = "abc";
}
#Override
public void onClick(final View v) {
final String[] contents = {"One", "Two", "Three"};
for(int i = 0; i < 3; ++i) {
final FooTask task = new FooTask(webView, result);
task.execute(contents[i]);
}
}
private class FooTask extends AsyncTask<String, Void, String> {
private final WebView resultView;
private String result;
// This is what I try to make it work right.
private synchronized String getResult() {
return result;
}
public FooTask(final WebView resultView, final String result) {
this.resultView = resultView;
this.result = result;
}
#Override
protected String doInBackground(final String... params) {
// Do a long time work randomly then returns a string.
return params[0];
}
#Override
protected void onPostExecute(final String content) {
result = getResult() + content;
resultView.loadData(result, "text/html", "utf-8");
}
}
}
Remove the private String result; line from the Async Task class.
There is nothing much to do here.. just add this line task.execute(contents[i]);
in postExecute() of AsynTask and make contents[i] as a class variable.. task.execute(contents[i]); call this twice since you want it to do "one" and "two"
In onPostExecute() you want to "return" your result somewhere. This is to say FooTask needs a place to put its result. A likely candidate would be some sort of method FooTask can call on its caller to place the result. If you do this note that the method must be synchronized, otherwise some of the returns may be lost.
Alternately you could give FooTask a Handler that it can send a Message to with the result. In this case, you will not need to synchronize anything since all the Messages will be sent to the main/UI thread which will process them serially.