When I retrieve the value in results activity. I get nothing, I guess the the value is not being passed from doInBackground to onPostExecute. Any idea what's wrong? or am I passing it the wrong way
class calculateTask extends AsyncTask<String, String, String>
{
#Override
protected String doInBackground(String... params) {
Thread t= new Thread();
try {
t.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int pix=0;
int circ=0;
int width1=mBitmap.getWidth();
int height1=mBitmap.getHeight();
for(int i=0;i<width1;i++)
{
for(int j=0;j<height1;j++)
{
if(mBitmap.getPixel(i, j)==Color.WHITE)
{
pix++;
}
if(mBitmap.getPixel(i, j)==Color.LTGRAY)
{
circ++;
}
}
}
int percentage=100-((pix-circ))*100 ;
String p=intToChar(array,percentage);
return p;
}
#Override
protected void onPostExecute(String p) {
Intent i= new Intent(circle1.this,results.class);
i.putExtra("perc", p);
startActivity(i);
//super.onPostExecute(result);
}
}
public String intToChar(char[] array, int pix) {
// TODO Auto-generated method stub
String b="";
int i = array.length - 1;
while (pix > 0 && i >= 0) {
array[i--] = (char) (48 + pix % 10);
pix /= 10;
} b = new String(array);
return b;
}
I would use a global variable. Then assign value to the global variable in doInBackground, and then retrieve it in onPostExecute.
EDIT:
Many things are wrong.
Here is one of my examples from code
private class Load extends AsyncTask<Void, Void, Void>
{
private ProgressDialog progressDialog;
private Context context;
private boolean internet, refresh;
public Load(Context context, boolean internet, boolean refresh)
{
this.internet = internet;
this.refresh = refresh;
this.context = context;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
progressDialog = ProgressDialog.show(context, null, "Loading data ...");
}
#Override
protected Void doInBackground(Void... voids)
{
taskComplete = false;
while (!taskComplete)
{
getData(this.internet);
try
{
Thread.sleep( 1000 );
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
populateData();
progressDialog.dismiss();
}
}
Try imitating this. getData sets taskComplete to true once it is done.
Related
I found many subject about but I can't get a solution, I'm doing a soap request in doInBackground method of asyncTask, and I want to get an Integer to know if the process is done, here I call my asyncTask:
Simulation.AsyncSoapCall task = new Simulation.AsyncSoapCall();
try {
Integer taskResult = task.execute().get();
} catch (Exception e) {
e.printStackTrace();
}
My AsyncTask class:
private class AsyncSoapCall extends AsyncTask<Void, Void, Integer> {
Integer result;
Boolean isInternetPresent = false;
Boolean isUrlAvailable = false;
ConnectionDetector cd;
AsyncSoapCall(){
}
#Override
protected Integer doInBackground(Void... params) {
cd = new ConnectionDetector(getActivity().getApplicationContext());
// get Internet status
isInternetPresent = cd.isConnectingToInternet();
// check for Internet status
if (isInternetPresent) {
String namespace = getResources().getString(R.string.NAMESPACE);
String url = getResources().getString(R.string.URL);
String soapaction = getResources().getString(R.string.SOAP_ACTION);
String login = getResources().getString(R.string.login);
String mdp = getResources().getString(R.string.mdp);
isUrlAvailable = cd.isUrlAvailable();
// check for Internet status
if (isUrlAvailable) {
String idApplication = Installation.id(getActivity());
SOAPContact soapContact = new SOAPContact(namespace, url, soapaction, login, mdp);
soapContact.saveParams(getResources().getString(R.string.origine), db);
result = 1;
} else {
result = 2;
}
} else {
result = 3;
}
return result;
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
#Override
protected void onProgressUpdate(Void... values) {
Log.i(TAG, "onProgressUpdate");
}
}
I don't get error my app crasha at this line:
Integer taskResult = task.execute().get();
try to get the value from onPostExecute like
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
int yourNum = result;
}
that's it
Did you read the doc?
https://developer.android.com/reference/android/os/AsyncTask.html
AsyncTask has no "get" method.
You need to define a OnPostExecute method which will be called when your task is over with your Integer as a parameter.
public class MyActivity extends Activity
{
private Integer myInteger;
private void blabla(){
Simulation.AsyncSoapCall task = new Simulation.AsyncSoapCall() {
#Override
protected void onPostExecute(Integer result) {
//... Your code here ...
MyActivity.this.myInteger = result;
MyActivity.this.myMethod(result);
}
}
try {
task.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
protected void myMethod(Integer integer){
}
}
Here is one method with the help of interfaces,
MainActivity.java
public class MainActivity extends AppCompatActivity {
static String TAG=MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AsyncSoapCall request = new AsyncSoapCall(new AsyncSoapCall.AsyncSoapInterface() {
#Override
public void callBack(String callBackValue) {
Log.d(TAG,callBackValue);
}
});
request.execute();
}
}
AsyncSoapCall.java
public class AsyncSoapCall extends AsyncTask<Void,Void,Void> {
interface AsyncSoapInterface{
void callBack(String callBackValue);
}
AsyncSoapInterface callbackObj;
AsyncSoapCall(AsyncSoapInterface callbackObj)
{
callbackObj = callbackObj;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
callbackObj.callBack("Your value");
}
}
Hi I have one issue in my AutoCompleteTextView with AsynTask web service.
If i type the word in AutoCompleteTextView very fast in Textwatcher, each time it goes to web service to fetch the data and displayed in Dropdown.
But if i type very fast,the dropdown shows previous data and again shows the current data in AutocompleteTextview and data is interrupted.How to avoid this issue in Android?
autoCompleteTextView1.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
itemClicked = false;
if (!beforeTextChanged.equals(s.toString()) && !selectedText) { //Here we check selectedText
System.out.println("itemClicked" + itemClicked);
sText = s.toString();
if (sText.length() > 2) {
try {
autoCompleteTextView1.dismissDropDown();
autoCompleteTextView1.setAdapter(null);
Async1 = new NewAsync1(getActivity(),sText);
Async1 .execute();
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
loadprogress_bar.setVisibility(View.INVISIBLE);
arrayList.clear();
adapter.clear();
adapter = new AutoCompleteAdapter(getActivity(), R.layout.customer_auto, R.id.customerNameLabel, arrayList);
autoCompleteTextView1.setAdapter(null);
autoCompleteTextView1.dismissDropDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
selectedText = false; //Clear selectedText flag
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
itemClicked = false;
beforeTextChanged = s.toString();
}
#Override
public void afterTextChanged(Editable s) {
itemClicked = false;
}
});
// NewOrderAsync Webservice
public class NewAsync1 extends AsyncTask<String, String, String> {
Activity mActivity;
JSONObject jObject;
String value;
ProgressDialog progressDialog;
public NewAsync1 (Activity mActivity,String value)
{
this.mActivity=mActivity;
this.value= value;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method
super.onPreExecute();
loadprogress_bar.setVisibility(View.VISIBLE);
}
#Override
protected String doInBackground(String... params) {
try {
String restUrl = "";
System.out.println("searchurl"+Url);
response = client.getJSONfromURL(restUrl);
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
#Override
protected void onPostExecute(String response) {
// TODO Auto-generated method stub
super.onPostExecute(response);
loadprogress_bar.setVisibility(View.INVISIBLE);
try{
JSONObject obj=new JSONObject(response);
JSONArray arr=obj.getJSONArray("ItemResult");
arraylist=ApiCalls.getArraylistfromJson(arr.toString());
arrayList = new ArrayList<String>();
for (int i = 0; i < arr.length(); i++) {
JSONObject obj1=arr.getJSONObject(i);
arrayList.add(obj1.getString("Name"));
}
//Create adapter
adapter = new AutoCompleteAdapter(getActivity(), R.layout.customer_auto, R.id.customerNameLabel, arrayList);
autoCompleteTextView1.setThreshold(1);
autoCompleteTextView1.setAdapter(adapter);
}catch (JSONException e){
e.printStackTrace();
}
if (!autoCompleteTextView1.isPopupShowing()) {
autoCompleteTextView1.showDropDown();
}
}
}
I'm calling async tasks in a loop on the onPostExecute() of an asyncTask. I want the control to wait until response of all the tasks is not receieved cause I'm collecting the response in a single arrayList which i have to pass a callback method after all the asyncTasks called in the loop are finished.
I'm avoiding to use the AsyncTask.get() as it blocks the main thread.
public class CallServerAsync extends AsyncTask<AsyncHttpRequestBo, Void, ArrayList<ArrayList<AsyncHttpRequestBo>>> implements PlatwareResponseListener {
PlatwareClientCommonUtils clientCommonFunctions;
Context context;
String url;
PlatwareResponseListener listener;
private ProgressDialog progressDialog;
ArrayList<AsyncHttpResponseBo> processResponseList = null;
ArrayList<AsyncHttpResponseBo> responseList = null;
public CallServerAsync(Context context, PlatwareResponseListener listener) {
this.context = context;
clientCommonFunctions = new PlatwareClientCommonUtils(context);
url = clientCommonFunctions.getServerUrlPrimary();
this.listener = listener;
responseList = new ArrayList<AsyncHttpResponseBo>();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(context, "Please wait", "Downloading...");
}
#Override
protected ArrayList<ArrayList<AsyncHttpRequestBo>> doInBackground(AsyncHttpRequestBo... params) {
ArrayList<ArrayList<AsyncHttpRequestBo>> requestLists = clientCommonFunctions.generateRequestList(params);
return requestLists;
}
#Override
protected void onPostExecute(ArrayList<ArrayList<AsyncHttpRequestBo>> result) {
for (ArrayList<AsyncHttpRequestBo> httpRequestList : result) {
CallserverSubAsync callserverSubAsync = new CallserverSubAsync(context, this);
callserverSubAsync.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, httpRequestList);
// ArrayList<AsyncHttpResponseBo> processResponseList = null;
// try {
// processResponseList = callserverSubAsync.get();
// } catch (InterruptedException e) {
// e.printStackTrace();
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
}
listener.onAsyncTaskCompleted(responseList, listener);
progressDialog.dismiss();
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
progressDialog.dismiss();
super.onCancelled();
}
#Override
public void onAsyncTaskCompleted(ArrayList<AsyncHttpResponseBo> responseList, PlatwareResponseListener listener) {
if (listener instanceof CallServerAsync) {
processResponseList = responseList;
for (AsyncHttpResponseBo responseBo : processResponseList) {
this.responseList.add(responseBo);
}
}
}
I have that AsyncTask code
public class DiceTask extends AsyncTask<Socket, Void, int[]> {
private int[] arrayFromServer = new int[8];
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected int[] doInBackground(Socket...params) {
Socket soc = params[0];
try {
ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
int[] tempArray = (int[]) (ois.readObject());
return tempArray;
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
#Override
protected void onProgressUpdate(Void...arg1) {
}
#Override
protected void onPostExecute(int[] result) {
arrayFromServer = result;
}
public int[] getTempDice() {
return arrayFromServer;
}
}
where is called this way into my main thread.
rollDiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDiceButton.setEnabled(false);
rollDice();
task.execute(socket);
tempArray = task.getTempDice();
printDice(tempArray,pDice);
clickableDice(pDice);
}
});
where I am getting a null tempArray. If I change my onPreExecute to this
#Override
protected void onPreExecute() {
super.onPreExecute();
for(int i = 0; i < arrayFromServer.length; i++) {
arrayFromServer[i] = 1;
}
}
I am getting my dice as it should, all are one. The code I am running into the rollDice() is this
public void rollDice() {
try {
DataOutputStream sout = new DataOutputStream(socket.getOutputStream());
String line = "dice";
PrintStream out = new PrintStream(sout);
out.println(line);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
and I can see the results in the server.
You don't need to implement onPostExecute in your AsyncTask class definition. You also don't need the getTempDice function. You just need to override onPostExecute in an anonymous class and run your UI code in it.
rollDiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDiceButton.setEnabled(false);
rollDice();
task = new DiceTask() {
#Override
public void onPostExecute(int[] result) {
tempArray = result;
printDice(tempArray,pDice);
clickableDice(pDice);
}
}.execute(socket);
}
});
Children of AsyncTask run in parallel with main Thread, you are trying access the attribute arrayFromServer right after to start the Thread. It's recommended you use a callback to retried the value wanted, making sure you get the value after Thread is done.
Making the follow changes can solve your problem. Let me know if you understand.
public class DiceTask extends AsyncTask<Socket, Void, int[]> {
public interface Callback {
void onDone(int[] arrayFromServer);
}
private Callback mCallback;
public DiceTask(Callback c) {
mCallback = c;
}
#Override
protected int[] doInBackground(Socket...params) {
Socket soc = params[0];
try {
ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
int[] tempArray = (int[]) (ois.readObject());
return tempArray;
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(int[] result) {
mCallback.onDone(result);
}
}
rollDiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDiceButton.setEnabled(false);
rollDice();
new DiceTask(new Callback() {
public void onDone(int[] tempArray) {
printDice(tempArray,pDice);
clickableDice(pDice);
}
}).execute(socket);
}
});
Could anyone explain why my progress dialog is not updating when my async task is running?
The progress dialog appears, but the percentage indicator does not increase at all.
Is there something obvious here?
private class DownloadFilesTask extends AsyncTask<ArrayList<String>, Integer, Long> {
private ProgressDialog mProgress;
#Override
protected void onPreExecute()
{
mProgress = new ProgressDialog(HelloActivity.this);
mProgress.setMessage("Fetching Image data..");
mProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgress.setCancelable(false);
//mProgress.setIndeterminate(false);
mProgress.show();
}
#Override
protected Long doInBackground(ArrayList<String>... urls) {
long totalSize = 0;
for(int i=0; i < dbLinks.size(); i++){
try {
....doe some stuff here
publishProgress((i/dbLinks.size()) * 100);
} catch (DbxException e) {
e.printStackTrace();
}
}
return totalSize;
}
#Override
protected void onProgressUpdate(Integer... progress) {
mProgress.setProgress(progress[0]);
}
#Override
protected void onPostExecute(Long result) {
mProgress.dismiss();
//use totalsize if necessary
Intent intentFB = new Intent(HelloActivity.this, PostActivity.class);
intentFB.putExtra("key", dbURLs);
startActivity(intentFB);
}
}
Integer math.
(i/dbLinks.size()) * 100
i/dbLinks.size() will be always 0 and multiplying it by 100 doesn't change it.
To fix it, consider setting progress bar max to dbLinks.size() and publish i as progress.
You may be getting the exception in your doInBackground method ,as i check sample demo it is working fine.
private class DownloadFilesTask extends AsyncTask<String, Integer, Long> {
private ProgressDialog mProgress;
#Override
protected void onPreExecute()
{
mProgress = new ProgressDialog(MainActivity.this);
mProgress.setMessage("Fetching Image data..");
mProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgress.setCancelable(false);
//mProgress.setIndeterminate(false);
mProgress.show();
}
#Override
protected Long doInBackground(String... progress) {
long totalSize = 0;
for(int i=0; i < 100; i++){
try {
publishProgress(i);
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return totalSize;
}
#Override
protected void onProgressUpdate(Integer... progress) {
mProgress.setProgress(progress[0]);
}
#Override
protected void onPostExecute(Long result) {
mProgress.dismiss();
}
}