How to refactor my code in AsyncTask without runOnUiThread? - android

Hello android developers! I have one problem with compatibility of my old codes and API 18.
All codes bellow runs perfectly in android 2.3. But when I try to run it on a newer API it crashes. Can I use it without runOnUiThread for updating my UI? What I shoud change? Thanks!
class GetDetails extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(QueryProduct.this);
pDialog.setMessage("Loading product details. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
int success;
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id", id));
JSONObject json = jsonParser.makeHttpRequest(
url_product_detials, "GET", params);
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
JSONArray productObj = json
.getJSONArray(TAG_PRODUCT);
JSONObject product = productObj.getJSONObject(0);
tvName = (TextView) findViewById(R.id.tvName);
tvName.setText(product.getString(TAG_NAME));
}else{
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return null;
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
}
}

Can I use it without runOnUiThread for updating my UI?
YES! Please do! Remove runOnUiThread() and return your result to onPostExecute() and update UI there. That's why the other methods exist.
The way you have it, you are running all of your background stuff on the UI which defeats the purpose of AsyncTask.
You can simply change your class definition to pass the int to onPostExecute()
class GetDetails extends AsyncTask<String, String, Integer>
then return success in doInBackground(). And check that value in onPostExecute() and update UI if success.
protected void onPostExecute(Integer result)
{
if (result == 1)
{
// code to update UI
Further ExplanationBe sure to read through the AsyncTask Docs really well. This class was created so that you can do your heavy-lifting such as network stuff on a background Thread (doInBackground()) and update the UI in it's built-in methods (the other 3).
onPreExecute() can update before the task starts such as for a
ProgressDialg
onProgressUpdate() can update while doInBackground() is still processing such as for the progress of a downloading file by calling publishProgress()
onPostExecute() is called when doInBackground() finishes to
update anything you need when the task finishes such as dismissing a
ProgressDialog

class GetDetails extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(QueryProduct.this);
pDialog.setMessage("Loading product details. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
// Do your Background Task Inside it and inside it when you want to update the Ui
// then call the method publishProgress. this call the method onProgressUpdate that
// run on the UI thread and inside it you update your UI
protected String doInBackground(String... params) {
int success;
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id", id));
JSONObject json = jsonParser.makeHttpRequest(
url_product_detials, "GET", params);
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
JSONArray productObj = json
.getJSONArray(TAG_PRODUCT);
JSONObject product = productObj.getJSONObject(0);
String result = product.getString(tvName)
// Need To Update the Ui so call the method publishProgress(result );
// this will call onProgressUpdate(String... values) method and
// String result i provide it to so that i can update the text view
// in it.
//Update in publish progress you can specify multiple String values
// and same received in onProgressUpdate as an array of values.
//publishProgress("value1","value2","value3")
publishProgress(result,"result2","result3");
}else{
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
// run on the Ui thread so inside it you can update your UI
protected void onProgressUpdate(String... values)
{
super.onProgressUpdate(values);
tvName = (TextView) findViewById(R.id.tvName);
tvName.setText(values[0]);
tvPrice = (TextView) findViewById(R.id.tvPrice);
tvPrice.setText(values[1]);
tvAdress = (TextView) findViewById(R.id.tvAdress);
tvAdress .setText(values[2]);
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
}
}

Related

when execute two AsyncTask in same fragment activity my application hanging and still loading

I am trying to execute two AsyncTask in the same fragment but when I run my application, my phone freezes and still loading this my code
when I execute one asynTask every thing is ok
this where it try to execute
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.w(LOG_TAG,"onActivityCreated------------");
// First AsyncTask execution called
new RecomenddedChaneel().execute();
//Second AsyncTask execution called
new Loadchannels().execute();
//this is the first asyncTask method
public class RecomenddedChaneel extends AsyncTask<String, Void, List<Video>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading channel list. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected List<Video> doInBackground(String... urls) {
channelForCategory= new ArrayList<Video>();
channelForCategory.clear();
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("uky", uk));
params.add(new BasicNameValuePair("per_page","10"));
JSONObject json = JsonFromHttp.makeHttpRequest(url+"getrecommended_top","POST", params);
try {
products=json.getJSONArray("products");
channelForCategory.clear();
listchD.clear();
String imageViewch =null;
for(int i =0; i <products.length();i++){
JSONObject details = products.getJSONObject(i);
String pid =details.getString("pid");
String cid=details.getString("cid");
String name= details.getString("name");
Log.v("",name);
if(details.has("imageViewch")){
imageViewch = details.getString("imageViewch");}
String image_url_path= imageurl+imageViewch;
channelForCategory.add(new Video(pid,cid,name,image_url_path));
listchD.add(new Video(name,pid));
Log.w(LOG_TAG,"pid*************all************"+pid);
Log.w(LOG_TAG,"cid*********all**********"+cid);
Log.w(LOG_TAG,"name********all**********"+name);
Log.w(LOG_TAG,"imagelink*********all***********"+imageViewch);
}
} catch (JSONException e){
Log.e("SetHttp", "Problem parsing News JSON results", e);
}
return null;
// return videos;
#Override
protected void onPostExecute(List<Video> video) {
pDialog.dismiss();
ChannelRecycleViewAdapter channelRecycleViewAdapter1
= new ChannelRecycleViewAdapter(getActivity(), channelForCategory, new ChannelRecycleViewAdapter.ListItemClickListener() {
#Override
public void onListItemClick(int clickedItemIndex) {
Video videoch= channelForCategory.get(clickedItemIndex);
String urlch=videoch.getmpid();
Intent inturl= new Intent(getActivity(),VideoPlayer.class);
inturl.putExtra("urlch",urlch);
inturl.putExtra("list_video_name", (Serializable) listchD);
startActivity(inturl);
Toast.makeText(getActivity(),
urlch, Toast.LENGTH_LONG).show();
}
});
recyclerView1.setAdapter(channelRecycleViewAdapter1);
and the second asynctask is the copy of the first asynctask.
I don't know why app hanging and still loading.

App crash when execute asynctask

my app crash when execute asynctask. I try to send data from android to the server but my app crashes when execute AsyncTask
` input input = new input();
input.execute();
mainActivity = this;
latitude = "-6.711647";
longitude ="108.5413";`
public class input extends AsyncTask<String, String, String>
{
HashMap<String, String> user = db.getUserDetails();
String email = user.get("email");
String success;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Sending Data to server...");
pDialog.setIndeterminate(false);
pDialog.show();
}
#Override
protected String doInBackground(String... arg0) {
String strEMAIL = email.toString();
String strNama = latitude.toString();
String strProdi = longitude.toString();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("email", strEMAIL));
params.add(new BasicNameValuePair("latitude", strNama));
params.add(new BasicNameValuePair("longitude", strProdi));
JSONObject json = jParser.makeHttpRequest(url, "POST", params);
try {
success = json.getString("success");
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Error",
Toast.LENGTH_LONG).show();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog once done
pDialog.dismiss();
if (success.equals("1"))
{
Toast.makeText(getApplicationContext(), "kirim data Sukses!!!", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "kirim data Gagal!!!", Toast.LENGTH_LONG).show();
}
}
}
this my complete code http://pastebin.com/jRdxeQKG
and this my logcat http://prntscr.com/7p3vbz
The reference db is null when you call new input() in onCreate().
Solution: Just initialize db before calling new input():
db = new SQLiteHandler(getApplicationContext());
input input = new input();
By the way, there are many issues from the design point of view, but this will solve (one of) the crash(es).
1 Starting the name of your class with a lowercase letter is bad practice.input should be Input and should be a little more descriptive.
2 Your db initialization should come before the call to execute AsyncTask
3 You need to really understand AsyncTask before using it. You declare three generic types for your AsyncTask
public class input extends AsyncTask<String, String, String> {
but none of them is used. Your doInBackground method should be returning an instance of type NameValuePair or JSONObject.
The first generic type of an AsyncTask is the params, that is what you intend to pass to your doInBackground method. You say it's String but do not pass in any String in input.execute(); This is not a problem right now because you haven't attempted to use args0, but your app will crash if you try to. I just think you should really read about AsyncTask first and understand the basics.It will save you a whole lot of trouble.Cheers.

Return string from Asynctask

i am trying to parse a jsonObject, but i cant get the result out of doInBackground into onPostExecute
Here is my AsyncTask code:
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MyActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
String auth2 = jsonObj.getString("auth");
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void auth2) {
super.onPostExecute(auth2);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
Toast.makeText(getApplicationContext(), "String retrived:" + auth2, Toast.LENGTH_SHORT).show();
}
}
I know its propably because i have return null there, but when i make return string then i get error.
I know in fact that jsonStr holds json data, i can see it in log:
Response:﹕ > {"user_info":{"auth":0}}
I put this code together from tutorials, thats why i dont completly understand it.
My goal is to see if auth is 0 or 1.
cant get the result out of doInBackground into onPostExecute
To return auth2 String from doInBackground :
1. Change return type of doInBackground method from Void to String:
#Override
protected String doInBackground(Void... arg0) {
}
2. Change AsyncTask last generic type from Void to String :
private class GetContacts extends AsyncTask<Void, Void, String>
3. Return auth2 from doInBackground :
String auth2 = jsonObj.getString("auth");
return auth2;
4. Change onPostExecute parameter type from Void to String :
#Override
protected void onPostExecute(String auth2) {
super.onPostExecute(auth2);
//...
Toast.makeText(getApplicationContext(),
"String retrived:" + auth2, Toast.LENGTH_SHORT).show();
}
read the documentation:
http://developer.android.com/reference/android/os/AsyncTask.html
private class GetContacts extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... arg0) {
...
return "askdjalskdj";
}
#Override
protected void onPostExecute(String auth2) {
Log.i("Output", auth2);
}
}
See the params I have set in the Generic implementation of Asynctask , see the defined return value from doInBackground and the Parameter type of onPostExecute
AsyncTask's generic types The three types used by an asynchronous task are the following:
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the
background computation.
Result, the type of the result of the
background computation.
Not all types are always used by an
asynchronous task. To mark a type as unused, simply use the type Void:
private class MyTask extends AsyncTask { ... }

AsyncTask has stopped calling doInBackground

I have been using this code for the last few days and up until today it has been working perfectly, but for some reason the Async task has stopped calling the doInBackground method. I have attempted the solution suggested here Android SDK AsyncTask doInBackground not running (subclass) but I just get the same result. The onPreExecute method gets called but then I am just left with the loading dialog. Has anybody experienced anything similar to this. I have included a copy of my code. MyAsncTask is executed as follows;
new MyAsyncTask().execute(email, password);
private class MyAsyncTask extends AsyncTask<String, Void, JSONObject>
{
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
Log.v(tag, "onPreExecute");
super.onPreExecute();
pDialog = new ProgressDialog(SignInPageActivity.this);
pDialog.setMessage("Logging in...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected JSONObject doInBackground(String... params) {
Log.v(tag, "doInBackground");
CustomerFunctions userFunction = new CustomerFunctions();
if (params.length != 2)
return null;
JSONObject json = userFunction.loginUser(params[0], params[1]);
return json;
}
#Override
protected void onPostExecute(JSONObject json)
{
Log.v(tag, "onPostExecute");
try {
if (json != null && json.getString(KEY_SUCCESS) != null) {
signInError.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully logged in
// Store user details in SQLite Database
DatabaseHandler databaseHandler = new DatabaseHandler(getApplicationContext());
JSONObject json_user = json.getJSONObject("customer");
// Clear all previous data in database
CustomerFunctions userFunction = new CustomerFunctions();
userFunction.logoutCustomer(getApplicationContext());
databaseHandler.addUser(json.getString(KEY_UID), json_user.getString(KEY_FIRST_NAME), json_user.getString(KEY_LAST_NAME), json_user.getString(KEY_EMAIL), json_user.getString(KEY_CURRENT_STAMPS), json_user.getString(KEY_TOTAL_STAMPS), json_user.getString(KEY_REWARDS_AVAILABLE), json_user.getString(KEY_REWARDS_CLAIMED), json_user.getString(KEY_CREATED_AT));
// Launch Dashboard Screen
Intent main = new Intent(getApplicationContext(), MainActivity.class);
// Close all views before launching Dashboard
// dismiss the dialog once done
pDialog.dismiss();
main.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(main);
// Close Registration Screen
finish();
}else{
// Error in login
signInError.setText("Incorrect username/password");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
try extending like this
private class MyAsyncTask<Params, Void, JSONObject> extends AsyncTask<Params, Void, JSONObject>
and use #Override for doInBackground

Android Async doinbackaground data to onpostexecute

I need some help with taking results from doinbackground to onpostexecute. The results are in the form of JSONArray. I want to populate two textviews in the UI through onpostexecute. There is no error in the code but nothing happens as it seems inpostexecute is not getting called. Please help. I have looked at several similar questions here and tried many things but unable to get it to work..thanks in advance. Please note private static final String TAG_LATEST_SCORES = "cricket_scores";
class PostScores extends AsyncTask<JSONArray, Void, JSONArray> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(NewScoreupdatescricketActivity.this);
pDialog.setMessage("Posting LiveScore Updates..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Creating product
* */
protected JSONArray doInBackground(JSONArray... args) {
String runs1 = runs.getText().toString();
String wicket1 = wicket.getText().toString();
String overs1 = over.getText().toString();
String rr1 = rr.getText().toString();
String team_name = null;
String bat1;
if (innings.isChecked() == false) {
bat1 = "1";
team_name = bat.getText().toString();
} else {
bat1 = "2";
team_name = bat.getText().toString();
}
if (rr1.equals("NA")) {
rr1 = "0";
}
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("runs", runs1));
params.add(new BasicNameValuePair("wickets", wicket1));
params.add(new BasicNameValuePair("id", id1));
params.add(new BasicNameValuePair("overs", overs1));
params.add(new BasicNameValuePair("rr", rr1));
params.add(new BasicNameValuePair("bat", bat1));
params.add(new BasicNameValuePair("team_name", team_name));
// getting JSON Object
// Note that create product url accepts POST method
JSONObject json = jsonParser.makeHttpRequest(url_create_product,
"POST", params);
// check log cat fro response
Log.d("Create Response", json.toString());
// check for success tag
try {
int success = json.getInt(TAG_SUCCESS);
pDialog.dismiss();
if (success == 1) {
latest_scores = json.getJSONArray(TAG_LATEST_SCORES);
} else {
}
} catch (JSONException e) {
e.printStackTrace();
}
pDialog.dismiss();
return latest_scores;
}
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(JSONArray latest_sc) {
// dismiss the dialog once done
try {
for (int i = 0; i < latest_sc.length(); i++) {
JSONObject c = latest_sc.getJSONObject(i);
String wickets = c.getString(TAG_WICKETS);
String runs = c.getString(TAG_RUNS);
score_inngs1.setText(wickets + runs);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Check your brackets. After your definition of doInBackground, you have an extra bracket - that one closes off your PostScores class, so your onPostExecute method is defined as a member of whatever class is enclosing PostScores, if any.
Also, you'll need to #Override the AsyncTask methods to provide your own implementation.

Categories

Resources