I'm Using inner AsyncTask to Calculate the Average from remote DB,
I get the result but
The problem is : The value of Average available only in "onPostExecute" , I want this value to be accessible in "On Create ()" so I can send it to another AsyncTask in the same Activity
public class Place_details extends Activity {
RatingBar PlaceRatingBar;
UserSessionManager session;
String ID;
Double [] Place_rates;
int Total_place_rates;
float Average_place_rates;
// JSON
JSONParser jsonparser;
JSONObject JSONObject;
ProgressDialog ProgressDialog;
JSONArray jsonArray1;
int value;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_place_details);
PlaceRatingBar = (RatingBar) findViewById (R.id.Place_rating);
jsonparser = new JSONParser();
//Session
session = new UserSessionManager(Place_details.this);
new getPlaceRating().execute() ;
// Here I get 0.0 and not the correct Average
Toast.makeText(Place_details.this, ""+Average_place_rates, Toast.LENGTH_SHORT).show();
} // End Of OnCreate
public class getPlaceRating extends AsyncTask<String,String,String>{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
ProgressDialog = new ProgressDialog(Place_details.this);
ProgressDialog.setTitle("Wait....");
ProgressDialog.setIndeterminate(false);
ProgressDialog.setCancelable(true);
ProgressDialog.show();
}
#Override
protected String doInBackground(String...parma) {
// TODO Auto-generated method stub
List<NameValuePair> list = new ArrayList<NameValuePair>();
// passing place_id value
list.add(new BasicNameValuePair("id",String_Place_id));
try {
JSONObject = jsonparser.makeHttpRequest("http://192.168.1.2/Yourguideapplication/Place_rating2.php", "POST", list);
Log.e("pass 1", "connection success ");
}
catch (Exception e) {
Log.e("Fail 1", "Fail connection");
}
try {
value = JSONObject.getInt("value");
if (value==1){
//Place Rating
jsonArray1 = JSONObject.getJSONArray("Place_rating");
Place_rates = new Double[jsonArray1.length()];
Total_place_rates =0;
for (int i = 0 ; i < jsonArray1.length() ; i++)
{
JSONObject object = jsonArray1.getJSONObject(i);
Place_rates[i] = object.getDouble("Rating_box");
Total_place_rates+= Place_rates[i];
}
} else {
value = 0;
}
} catch (Exception e){
Log.d("ERORR",e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (value == 1){
//Place Rating
Average_place_rates = (float) (Total_place_rates/jsonArray1.length());
PlaceRatingBar.setRating((float) Average_place_rates);
} else {
Toast.makeText(Place_details.this, "Error", Toast.LENGTH_LONG).show();
}
ProgressDialog.dismiss();
}
}
}
Thank you
You can create something like
private interface CallbackListener<T> {
void onComputingFinished(T arg);
}
Make your activity implement this interface.
public class Place_details extends Activity implements CallbackListener<String> {
#Override
public void onComputingFinished(String arg) {
//do your stuff here
}
And register it as listener in your AsynTask class (create field and constructor in you AsyncTask class):
public class GetPlaceRating extends AsyncTask<String,String,String>{
private CallbackListener<String> mListener;
public GetPlaceRating(CallbackListener<String> listener) {
mListener = listener;
}
And when starting task
new GetPlaceRating(this).execute() ;
And in onPostExecute call
if (mListener != null) mListener.onComputingFinished(*your arg*);
I used String to replace generic T in this example, hope you understand you can use whatever you want.
EDITED:
If arguments are of the same type you can change signature of interface to:
private interface CallbackListener<T> {
void onComputingFinished(T ...args);
}
And access them as an array: args[0], args[1].
Or just specify what concrete arguments you want to pass, for example String, int and SomeClass:
private interface CallbackListener {
void onComputingFinished(String str, int value, SomeClass obj);
}
Related
I want to display this textview "txtCalculate" which comes from the class CustomerMapActivity which is displayed in the activity_map_customer layout in another layout which is activity_bon_de_commande, of the class BonDeCommande.
the problem is I don't know how to do it
I'm new to java programming
thank you
public void readValues(){
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Query lastQuery = ref.child("ride_info").orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()){
double value0_float = ds.child("pickup").child("lat").getValue(Double.class);
double value1_float = ds.child("pickup").child("lng").getValue(Double.class);
double value2_float = ds.child("destination").child("lat").getValue(Double.class);
double value3_float = ds.child("destination").child("lng").getValue(Double.class);
String pickupLat = String.valueOf(value0_float);
String pickupLng = String.valueOf(value1_float);
String destiLat = String.valueOf(value2_float);
String destiLng = String.valueOf(value3_float);
String requestUrl=null;
try {
requestUrl = "https://maps.googleapis.com/maps/api/directions/json?"+
"mode=driving&"
+"transit_routing_preference=less_driving&"
+"origin="+pickupLat+","+pickupLng+"&"
+"destination="+destiLat+","+destiLng+"&"
+"key="+getResources().getString(R.string.google_maps_key);
Log.e("LINK",requestUrl);
mService.getPath(requestUrl).enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
try {
JSONObject jsonObject = new JSONObject(response.body().toString());
JSONArray routes = jsonObject.getJSONArray("routes");
JSONObject object = routes.getJSONObject(0);
JSONArray legs = object.getJSONArray("legs");
JSONObject legsObject = legs.getJSONObject(0);
//Get distance
JSONObject distance = legsObject.getJSONObject("distance");
String distance_text = distance.getString("text");
//use regex to extract double from string
//This regex will remove all text not digit
Double distance_value= Double.parseDouble(distance_text.replaceAll("[^0-9\\\\.]+",""));
//Get Time
JSONObject time = legsObject.getJSONObject("duration");
String time_text = time.getString("text");
Integer time_value = Integer.parseInt(time_text.replaceAll("\\D+",""));
String final_calculate = String.format("%.2f €",
TypeObject.getPrice(distance_value,time_value));
HERE -----> txtCalculate.setText(final_calculate);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
mCurrentRide.cancelRide();
endRide();
}
});
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
mCurrentRide.cancelRide();
endRide();
}
});
}
screenshot of my screen
You need to Create an Interface with an update method, declare in your Activity and after, pass as parameter to your handler object that gets the data.
Don't forget If you're getting the data in a different Thread, you need to update your views always in an UI Thread or in the Main Thread.
Here Follow some example code:
Your Activity or Fragment
public class MainActivity extends AppCompatActivity
implements UpdateViewCallback { // implement the interface here
private TextView textView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
textView = findViewById(R.id.textView);
// Pass the interface in your Object that makes the async work
final AsyncWork asyncWork = new AsyncWork(this);
// Running
Thread thread = new Thread(asyncWork);
thread.start();
}
/**
* UpdateViewCallback
* #param result
*/
#Override
public void updateView(final String result) {
// Always update View on MainThread or an UI Thread, or else issues will start to happening
this.runOnUiThread(new Runnable() {
public void run() {
// Check if View is null since you're updating in a thread async
if (textView != null) {
textView.setText(result);
}
}
});
}
}
Your Interface:
public interface UpdateViewCallback {
void updateView(String result);
}
Your Object to handle the Async Work:
public class AsyncWork implements Runnable {
private UpdateViewCallback updateViewCallback;
public AsyncWork(UpdateViewCallback updateViewCallback) {
this.updateViewCallback = updateViewCallback;
}
/**
* Async Work here
*/
#Override
public void run() {
// Do some Work and after update using the interface you passed in the constructor
updateViewCallback.updateView("This is a test");
}
}
In my AsyncTask I do a quite a long operation inside doInBackground() which assigns a value to a variable after completion of doInBackground().
I use the value of that variable to setup a part of the user interface in postExecute().
The problem is that doinbackground() is quite a long operation and postExecute() finishes first. That way I fail to obtain the value.
Here's what the problem is
private class bigwork extends AsyncTask<String, Void, Boolean> {
String foo = null;
#Override
protected void onPreExecute() {
}
#Override
protected Boolean doInBackground(final String... args) {
// Long operation sets variable 'foo' a new value
}
#Override
protected void onPostExecute(final Boolean success) {
// Make use of foo here
}
The problem is the value of foo I get in postExecute() is still null.
Usually you would pass the String directly to onPostExecute:
private class bigwork extends AsyncTask<String, Void, String>
{
#Override
protected void onPreExecute() {
}
#Override
protected Boolean doInBackground(final String... args) {
// Long operation
set variable 'foo' a new value
return foo;
}
#Override
protected void onPostExecute(String foo) {
if (foo != null) {
// success
}
// Make use of foo here
}
Override onPostExecute() function to perform some task after doInBackground() function has finished.Like this:
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
ServiceHandler sh = new ServiceHandler();
jsonStr=sh.makeServiceCall(arg0[0], ServiceHandler.GET);
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.i("jsin", jsonStr);
if(pd.isShowing()){
pd.dismiss();
}
try {
js = new JSONObject(jsonStr);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JSONArray results =null;
try {
results = js.getJSONArray("results");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i = 0; i< results.length();i++)
{
JSONObject c = null;
try {
c = results.getJSONObject(i);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
placeName = c.getString(TAG_NAME);
ratings = c.getDouble(TAG_RATING);
HashMap<String, String> rest = new HashMap<String, String>();
rest.put(TAG_NAME, placeName);
rest.put(TAG_RATING, ratings+"");
placeList.add(rest);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ListAdapter adapter = new SimpleAdapter(getActivity().getApplicationContext(), placeList, R.layout.list_item, new String[]{TAG_NAME}, new int[]{R.id.list_text});
lv.setAdapter(adapter);
}
I am making http request in my doInBackground and after successful reply i am parsing json in onPostExecute() and displaying in a listview and obviously this code is in class extending AsyncTask class.
You should pass the parameter directly to onPostExecute. Quoting from the Android Developer Reference:
protected void onPostExecute (Result result)
Runs on the UI thread after doInBackground(Params...). The specified result is the value returned by doInBackground(Params...).
In case you need to pass more than one parameter wrap them in a class like:
public class MyClass
{
public String string1;
public String string2;
public MyClass(String a, String b){
string1 = a;
string2 = b;
}
}
Hope this helps.
Best regards.
I have a MainActivity whose onCreate is
//called when activity first created
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchText = (EditText) findViewById(R.id.searchText);
utils = new Utils(MainActivity.this);
db=(new SQLLiteDbHelper(MainActivity.this,utils.getInt(Key.Db_version))).getReadableDatabase();
request = new WebRequest(this);
status = new AsynGetEmployeeStatus();
}
and sqlitehelper onCreate and constructor is
//constructor
public SQLLiteDbHelper(Context context,int dbVersion) {
super(context,DATABASE_NAME, null, dbVersion);
this.context = context;
Log.d("tag","db version is "+DATABASE_VERSION);
crypt = new Cryptography();
utils = new Utils(context);
}
//called when activity first created
#Override
public void onCreate(final SQLiteDatabase db) {
String s;
try {
//new LoadData().execute(db);
new AsynNetworkOperation(context, ServiceUri.AccessMethod.GET, "loading").execute(ServiceUri.SERVICE_URI+"s?d=abc"); //this line throw exception
} catch (Throwable t) {
Toast.makeText(context, t.toString(), Toast.LENGTH_LONG).show();
Log.d("tag",t.toString());
}
}
my AsynNetworkOperation class is
public class AsynNetworkOperation extends AsyncTask<String,Void,Void>{
private Context context = null;
private ProgressDialog dialog = null;
private String title = "";
private WebRequest request = null;
private String accessMethod = "";
private HttpResponse response = null;
AsynResponse delegate = null;
public AsynNetworkOperation(Context context, String method, String dialogTitle)
{
this.context = context;
accessMethod = method;
this.title = dialogTitle;
delegate = (AsynResponse) context;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog = new ProgressDialog(context);
dialog.setMessage(title);
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
#Override
protected Void doInBackground(String... data) {
// TODO Auto-generated method stub
request = new WebRequest(context);
if(accessMethod.equals(ServiceUri.AccessMethod.GET)){
response = request.makeHttpGetCall(data[0]);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
delegate.responseResult(response);
dispose();
}
private void dispose()
{
context = null;
dialog = null;
title = "";
request = null;
accessMethod = "";
delegate = null;
}
}
AsynResponse is
public interface AsynResponse {
/**
* This will called when AysncTask finished its execution or when onPostExecute called
*
* #param response
*/
public void responseResult(HttpResponse response);
}
My problem is , whenever sqlitehelper try to execute new AsynNetworkOperation in its onCreate , it throw exception
java.lang.ClassCastException: android.app.MainActivity
can anyone help me finding the problem why it is throwing exception.
Thanks
Well this looks like it's probably the problem:
delegate = (AsynResponse) context;
You're casting the context variable to AsynResponse, and that context variable comes from here:
new SQLLiteDbHelper(MainActivity.this, ...)
So it isn't an AsynResponse. It's not even clear what AsynResponse is, but MainActivity presumably isn't compatible with it.
You should work out what you really want that value to be, potentially passing it separately to the Context.
I'm using Android SDK 4.0 API14 and I want to run multiple AsyncTask in one class, I want the called async task to wait while the one before it is finished, but is seems I can't accomplish this, even if I test the status of the one currently being executed. this is my code :
if(isNetworkAvailable()){
new SpinnerTask().execute();
new RiderTask().execute();
new BankTask().execute();
}
//spinner bank
public class BankTask extends AsyncTask<Void, Void, String>{
String url="http://128.21.30.37:8080/E-Policy/ios/spaj_bank.htm?type=pusat";
public BankTask(){
this.url=url;
System.out.println(url);}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog=new ProgressDialog(Menu_SPPAJ.this);
dialog = ProgressDialog.show(Menu_SPPAJ.this, "Mohon Menunggu", "Penarikan data Rider..");}
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
String result = "";
try {
result = Connection.get(url);
System.out.println("tes " + result);
} catch (Exception e) {
// TODO: handle exception
result = "";
}
return result;
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
// TODO Auto-generated method stub
super.onPostExecute(result);
// Response(result.replace("\n", "").trim());
System.out.println("done for Bank");
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray PRODUK = jsonObject.getJSONArray("BANK PUSAT");
for (int i=0; i<PRODUK.length();i++){
JSONObject spinner = PRODUK.getJSONObject(i);
String LSBP_NAMA = spinner.optString("LSBP_NAMA");
int LSBP_ID = spinner.optInt("LSBP_ID");
helper.InsertBank(LSBP_ID, LSBP_NAMA);
// ListSpinner.add(VarSpinner);
System.out.println("tes VarSpinner");
}
}catch (Exception e) {
Log.d("TES", e.getMessage());
}
}
}
//spinner bank
public class CabBankTask extends AsyncTask<Void, Void, String>{
String url="http://128.21.30.37:8080/E-Policy/ios/spaj_bank.htm?type=cabang";
public CabBankTask(){
this.url=url;
System.out.println(url);}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog=new ProgressDialog(Menu_SPPAJ.this);
dialog = ProgressDialog.show(Menu_SPPAJ.this, "Mohon Menunggu", "Penarikan data Rider..");}
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
String result = "";
try {
result = Connection.get(url);
System.out.println("tes " + result);
} catch (Exception e) {
// TODO: handle exception
result = "";
}
return result;
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
// TODO Auto-generated method stub
super.onPostExecute(result);
// Response(result.replace("\n", "").trim());
System.out.println("done for Cabang");
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray PRODUK = jsonObject.getJSONArray("BANK CABANG");
for (int i=0; i<PRODUK.length();i++){
JSONObject spinner = PRODUK.getJSONObject(i);
int LSBP_ID = spinner.optInt("LSBP_ID");
int LBN_ID = spinner.optInt("LBN_ID");
String LBN_NAMA = spinner.optString("LBN_NAMA");
helper.InsertCabBank(LSBP_ID, LBN_ID, LBN_NAMA);
// ListSpinner.add(VarSpinner);
System.out.println("tes VarSpinner");
}
}catch (Exception e) {
Log.d("TES", e.getMessage());
}
}
}
//spinner produk
public class SpinnerTask extends AsyncTask<Void, Void, String>{
// String url="http://epolicy.sinarmasmsiglife.co.id/ios/spaj_prod.htm?model=1";
String url="http://128.21.30.37:8080/E-Policy/ios/spaj_prod.htm?type=bancass";
public SpinnerTask(){
this.url=url;
System.out.println(url);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog=new ProgressDialog(Menu_SPPAJ.this);
// dialog = ProgressDialog.show(Menu_SPPAJ.this, "Mohon Menunggu", "Penarikan data Produk..");
}
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
String result = "";
try {
result = Connection.get(url);
System.out.println("tes " + result);
} catch (Exception e) {
// TODO: handle exception
result = "";
}
return result;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
// dialog.dismiss();
super.onPostExecute(result);
fetchResponse(result.replace("\n", "").trim());
System.out.println("done for product");
}
}
private void fetchResponse(String result) {
if (!result.equals("")) {
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray PRODUK = jsonObject.getJSONArray("PRODUK");
for (int i=0; i<PRODUK.length();i++){
JSONObject spinner = PRODUK.getJSONObject(i);
String LSBS_ID = spinner.optString("LSBS_ID");
String LSBS_NAME = spinner.optString("LSBS_NAME");
helper.InsertSpin_Produk(LSBS_ID, LSBS_NAME);
// ListSpinner.add(VarSpinner);
System.out.println("tes VarSpinner");
JSONArray PRODUK1 = spinner.getJSONArray("SUB_PRODUK");
for (int j=0; j<PRODUK1.length();j++){
JSONObject sub = PRODUK1.getJSONObject(j);
String LSDBS_NUMBER = sub.optString("LSDBS_NUMBER");
String LSDBS_NAME = sub.optString("LSDBS_NAME");
helper.InsertSpin_SubProduk(LSBS_ID,LSBS_NAME,LSDBS_NUMBER, LSDBS_NAME);
System.out.println("tes VarSpinner 1\2");
}
}
}
catch (Exception e) {
Log.d("TES", e.getMessage());
}
}
}
//Rider
public class RiderTask extends AsyncTask<Void, Void, String>{
String url="http://128.21.30.37:8080/E-Policy/ios/spaj_prod.htm?type=rider";
public RiderTask(){
this.url=url;
System.out.println(url);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog=new ProgressDialog(Menu_SPPAJ.this);
dialog = ProgressDialog.show(Menu_SPPAJ.this, "Mohon Menunggu", "Penarikan data Rider..");
}
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
String result = "";
try {
result = Connection.get(url);
System.out.println("tes " + result);
} catch (Exception e) {
// TODO: handle exception
result = "";
}
return result;
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
// TODO Auto-generated method stub
super.onPostExecute(result);
Response(result.replace("\n", "").trim());
System.out.println("done for ridern");
}
}
is there any way to run multiple Asynctask in one class? thank u very much
Have a look on the AsyncTask.executeOnExecutor() method. It will run AsyncTasks in parallel. But make sure that the Tasks you run are independent from each other. As mentioned in the docs there is no given order in which the Tasks will be executed.
Call your Tasks like this:
new SpinnerTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
What you can do is, you can call second AsyncTask on onPostExecute() of first AsyncTask and so on.
e.g
public class FirstAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// your code
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// new SecondAsyncTask().execute();
}}
Can anyone help me out that why is the function getInBackground is not running i want to fetch the data from parse in android.
This is my class which calls the function of fetchData(String themeId) in parseManipulate class
public class selectTheme extends Activity implements OnClickListener{
Button gBtn;
Button rBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.themeselection);
String themeid = "ECGo4oSKgU";
ParseManipulate pm = new ParseManipulate();
pm.fetchData(themeid);
/* gBtn = (Button)findViewById(R.id.greentheme);
rBtn = (Button)findViewById(R.id.redtheme);
gBtn.setOnClickListener(this);
rBtn.setOnClickListener(this);
*/
}
And this is my fetchData() function in ParseManipulate class.compiler does not run the function getInBackground() function and jumps at the end of function closing bracket
public class ParseManipulate {
public void fetchData(String ThemeId)
{
ParseQuery<ParseObject> pq = ParseQuery.getQuery("testThemes");
pq.getInBackground(ThemeId, new GetCallback<ParseObject>(){
#Override
public void done(ParseObject object, ParseException e) {
// TODO Auto-generated method stub
if(e == null)
{
// value = object.getString("ThemeName");
Log.d("ParseObject", ""+object.getString("ThemeName"));
}
else
{
// Toast.makeText(getApplicationContext(), "error in data fetching", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Instead of
Log.d("ParseObject", ""+object.getString("ThemeName"));
Use it like this
Log.d("ParseObject", ""+object.fetchIfNeeded().getString("ThemeName"));