protected void onPostExecute error - java

When I try to implement the onPostExecute method it gives me an error to remove #Override and that a super class or method needs to be called. However, I did call the superclass and such. Here is my code of my Asynctask.
public class parsenfill extends AsyncTask<Void,Void,Void> {
#Override
protected Void doInBackground(Void... params) {
try {
JsonParsing parse = new JsonParsing(url);
parse.parseFile(3, urls);
return null;
}
catch(Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void...voids ) {
super.onPostExecute(voids);
//Body of method
}
}

Remove the ... from the method signature. The parameter type of onPostExecute is the return type of doInBackground() i.e. just plain Void in your case.

Try this
private class MyAsyncClass extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
/**
* invoked on the UI thread before the task is executed. This step
* is normally used to setup the task, for instance by showing a
* progress bar in the user interface.
*/
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
/**
* Invoked on the background thread immediately after onPreExecute()
* finishes executing. This step is used to perform background
* computation that can take a long time. The parameters of the
* asynchronous task are passed to this step.
*/
return null;
}
#Override
protected void onPostExecute(Void result) {
/**
* Invoked on the UI thread after the background computation
* finishes. The result of the background computation is passed to
* this step as a parameter.
*/
super.onPostExecute(result);
}
}
Then you have to call this async class on UI thread like this.
new MyAsyncClass().execute();

Wrong:
#Override
protected void onPostExecute(Void...voids ) {
super.onPostExecute(voids);
//Body of method
}
because ... stands for string array and your background returns void.
Correct:
#Override
protected void onPostExecute(Void voids ) {
super.onPostExecute(voids);
//Body of method
}

Related

A better way of getting a result from an Async call while passing a function [duplicate]

I have this two classes. My main Activity and the one that extends the AsyncTask, Now in my main Activity I need to get the result from the OnPostExecute() in the AsyncTask. How can I pass or get the result to my main Activity?
Here is the sample codes.
My main Activity.
public class MainActivity extends Activity{
AasyncTask asyncTask = new AasyncTask();
#Override
public void onCreate(Bundle aBundle) {
super.onCreate(aBundle);
//Calling the AsyncTask class to start to execute.
asyncTask.execute(a.targetServer);
//Creating a TextView.
TextView displayUI = asyncTask.dataDisplay;
displayUI = new TextView(this);
this.setContentView(tTextView);
}
}
This is the AsyncTask class
public class AasyncTask extends AsyncTask<String, Void, String> {
TextView dataDisplay; //store the data
String soapAction = "http://sample.com"; //SOAPAction header line.
String targetServer = "https://sampletargeturl.com"; //Target Server.
//SOAP Request.
String soapRequest = "<sample XML request>";
#Override
protected String doInBackground(String... string) {
String responseStorage = null; //storage of the response
try {
//Uses URL and HttpURLConnection for server connection.
URL targetURL = new URL(targetServer);
HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setChunkedStreamingMode(0);
//properties of SOAPAction header
httpCon.addRequestProperty("SOAPAction", soapAction);
httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
httpCon.setRequestMethod(HttpPost.METHOD_NAME);
//sending request to the server.
OutputStream outputStream = httpCon.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.write(soapRequest);
writer.flush();
writer.close();
//getting the response from the server
InputStream inputStream = httpCon.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);
int intResponse = httpCon.getResponseCode();
while ((intResponse = bufferedReader.read()) != -1) {
byteArrayBuffer.append(intResponse);
}
responseStorage = new String(byteArrayBuffer.toByteArray());
} catch (Exception aException) {
responseStorage = aException.getMessage();
}
return responseStorage;
}
protected void onPostExecute(String result) {
aTextView.setText(result);
}
}
Easy:
Create interface class, where String output is optional, or can be whatever variables you want to return.
public interface AsyncResponse {
void processFinish(String output);
}
Go to your AsyncTask class, and declare interface AsyncResponse as a field :
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
public AsyncResponse delegate = null;
#Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
}
In your main Activity you need to implements interface AsyncResponse.
public class MainActivity implements AsyncResponse{
MyAsyncTask asyncTask =new MyAsyncTask();
#Override
public void onCreate(Bundle savedInstanceState) {
//this to set delegate/listener back to this class
asyncTask.delegate = this;
//execute the async task
asyncTask.execute();
}
//this override the implemented method from asyncTask
#Override
void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
}
}
UPDATE
I didn't know this is such a favourite to many of you. So here's the simple and convenience way to use interface.
still using same interface. FYI, you may combine this into AsyncTask class.
in AsyncTask class :
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
// you may separate this or combined to caller class.
public interface AsyncResponse {
void processFinish(String output);
}
public AsyncResponse delegate = null;
public MyAsyncTask(AsyncResponse delegate){
this.delegate = delegate;
}
#Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
}
do this in your Activity class
public class MainActivity extends Activity {
MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse(){
#Override
void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
}
}).execute();
}
Or, implementing the interface on the Activity again
public class MainActivity extends Activity
implements AsyncResponse{
#Override
public void onCreate(Bundle savedInstanceState) {
//execute the async task
new MyAsyncTask(this).execute();
}
//this override the implemented method from AsyncResponse
#Override
void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
}
}
As you can see 2 solutions above, the first and third one, it needs to create method processFinish, the other one, the method is inside the caller parameter. The third is more neat because there is no nested anonymous class.
Tip: Change String output, String response, and String result to different matching types in order to get different objects.
There are a few options:
Nest the AsyncTask class within your Activity class. Assuming you don't use the same task in multiple activities, this is the easiest way. All your code stays the same, you just move the existing task class to be a nested class inside your activity's class.
public class MyActivity extends Activity {
// existing Activity code
...
private class MyAsyncTask extends AsyncTask<String, Void, String> {
// existing AsyncTask code
...
}
}
Create a custom constructor for your AsyncTask that takes a reference to your Activity. You would instantiate the task with something like new MyAsyncTask(this).execute(param1, param2).
public class MyAsyncTask extends AsyncTask<String, Void, String> {
private Activity activity;
public MyAsyncTask(Activity activity) {
this.activity = activity;
}
// existing AsyncTask code
...
}
You can try this code in your Main class.
That worked for me, but i have implemented methods in other way
try {
String receivedData = new AsyncTask().execute("http://yourdomain.com/yourscript.php").get();
}
catch (ExecutionException | InterruptedException ei) {
ei.printStackTrace();
}
I felt the below approach is very easy.
I have declared an interface for callback
public interface AsyncResponse {
void processFinish(Object output);
}
Then created asynchronous Task for responding all type of parallel requests
public class MyAsyncTask extends AsyncTask<Object, Object, Object> {
public AsyncResponse delegate = null;//Call back interface
public MyAsyncTask(AsyncResponse asyncResponse) {
delegate = asyncResponse;//Assigning call back interfacethrough constructor
}
#Override
protected Object doInBackground(Object... params) {
//My Background tasks are written here
return {resutl Object}
}
#Override
protected void onPostExecute(Object result) {
delegate.processFinish(result);
}
}
Then Called the asynchronous task when clicking a button in activity Class.
public class MainActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
Button mbtnPress = (Button) findViewById(R.id.btnPress);
mbtnPress.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {
#Override
public void processFinish(Object output) {
Log.d("Response From Asynchronous task:", (String) output);
mbtnPress.setText((String) output);
}
});
asyncTask.execute(new Object[] { "Your request to aynchronous task class is giving here.." });
}
});
}
}
Thanks
This answer might be late but I would like to mention few things when your Activity dependent on AsyncTask. That would help you in prevent crashes and memory management. As already mentioned in above answers go with interface, we also say them callbacks. They will work as an informer, but never ever send strong reference of Activity or interface always use weak reference in those cases.
Please refer to below screenshot to findout how that can cause issues.
As you can see if we started AsyncTask with a strong reference then there is no guarantee that our Activity/Fragment will be alive till we get data, so it would be better to use WeakReference in those cases and that will also help in memory management as we will never hold the strong reference of our Activity then it will be eligible for garbage collection after its distortion.
Check below code snippet to find out how to use awesome WeakReference -
MyTaskInformer.java Interface which will work as an informer.
public interface MyTaskInformer {
void onTaskDone(String output);
}
MySmallAsyncTask.java AsyncTask to do long running task, which will use WeakReference.
public class MySmallAsyncTask extends AsyncTask<String, Void, String> {
// ***** Hold weak reference *****
private WeakReference<MyTaskInformer> mCallBack;
public MySmallAsyncTask(MyTaskInformer callback) {
this.mCallBack = new WeakReference<>(callback);
}
#Override
protected String doInBackground(String... params) {
// Here do whatever your task is like reading/writing file
// or read data from your server or any other heavy task
// Let us suppose here you get response, just return it
final String output = "Any out, mine is just demo output";
// Return it from here to post execute
return output;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// Here you can't guarantee that Activity/Fragment is alive who started this AsyncTask
// Make sure your caller is active
final MyTaskInformer callBack = mCallBack.get();
if(callBack != null) {
callBack.onTaskDone(s);
}
}
}
MainActivity.java This class is used to start my AsyncTask implement interface on this class and override this mandatory method.
public class MainActivity extends Activity implements MyTaskInformer {
private TextView mMyTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMyTextView = (TextView) findViewById(R.id.tv_text_view);
// Start your AsyncTask and pass reference of MyTaskInformer in constructor
new MySmallAsyncTask(this).execute();
}
#Override
public void onTaskDone(String output) {
// Here you will receive output only if your Activity is alive.
// no need to add checks like if(!isFinishing())
mMyTextView.setText(output);
}
}
You can do it in a few lines, just override onPostExecute when you call your AsyncTask. Here is an example for you:
new AasyncTask()
{
#Override public void onPostExecute(String result)
{
// do whatever you want with result
}
}.execute(a.targetServer);
I hope it helped you, happy codding :)
in your Oncreate():
`
myTask.execute("url");
String result = "";
try {
result = myTask.get().toString();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}`
Why do people make it so hard.
This should be sufficient.
Do not implement the onPostExecute on the async task, rather implement it on the Activity:
public class MainActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState) {
//execute the async task
MyAsyncTask task = new MyAsyncTask(){
protected void onPostExecute(String result) {
//Do your thing
}
}
task.execute("Param");
}
}
You can call the get() method of AsyncTask (or the overloaded get(long, TimeUnit)). This method will block until the AsyncTask has completed its work, at which point it will return you the Result.
It would be wise to be doing other work between the creation/start of your async task and calling the get method, otherwise you aren't utilizing the async task very efficiently.
You can write your own listener. It's same as HelmiB's answer but looks more natural:
Create listener interface:
public interface myAsyncTaskCompletedListener {
void onMyAsynTaskCompleted(int responseCode, String result);
}
Then write your asynchronous task:
public class myAsyncTask extends AsyncTask<String, Void, String> {
private myAsyncTaskCompletedListener listener;
private int responseCode = 0;
public myAsyncTask() {
}
public myAsyncTask(myAsyncTaskCompletedListener listener, int responseCode) {
this.listener = listener;
this.responseCode = responseCode;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String result;
String param = (params.length == 0) ? null : params[0];
if (param != null) {
// Do some background jobs, like httprequest...
return result;
}
return null;
}
#Override
protected void onPostExecute(String finalResult) {
super.onPostExecute(finalResult);
if (!isCancelled()) {
if (listener != null) {
listener.onMyAsynTaskCompleted(responseCode, finalResult);
}
}
}
}
Finally implement listener in activity:
public class MainActivity extends AppCompatActivity implements myAsyncTaskCompletedListener {
#Override
public void onMyAsynTaskCompleted(int responseCode, String result) {
switch (responseCode) {
case TASK_CODE_ONE:
// Do something for CODE_ONE
break;
case TASK_CODE_TWO:
// Do something for CODE_TWO
break;
default:
// Show some error code
}
}
And this is how you can call asyncTask:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Some other codes...
new myAsyncTask(this,TASK_CODE_ONE).execute("Data for background job");
// And some another codes...
}
Hi you can make something like this:
Create class which implements AsyncTask
// TASK
public class SomeClass extends AsyncTask<Void, Void, String>>
{
private OnTaskExecutionFinished _task_finished_event;
public interface OnTaskExecutionFinished
{
public void OnTaskFihishedEvent(String Reslut);
}
public void setOnTaskFinishedEvent(OnTaskExecutionFinished _event)
{
if(_event != null)
{
this._task_finished_event = _event;
}
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params)
{
// do your background task here ...
return "Done!";
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
if(this._task_finished_event != null)
{
this._task_finished_event.OnTaskFihishedEvent(result);
}
else
{
Log.d("SomeClass", "task_finished even is null");
}
}
}
Add in Main Activity
// MAIN ACTIVITY
public class MyActivity extends ListActivity
{
...
SomeClass _some_class = new SomeClass();
_someclass.setOnTaskFinishedEvent(new _some_class.OnTaskExecutionFinished()
{
#Override
public void OnTaskFihishedEvent(String result)
{
Toast.makeText(getApplicationContext(),
"Phony thread finished: " + result,
Toast.LENGTH_SHORT).show();
}
});
_some_class.execute();
...
}
Create a static member in your Activity class. Then assign the value during the onPostExecute
For example, if the result of your AsyncTask is a String, create a public static string in your Activity
public static String dataFromAsyncTask;
Then, in the onPostExecute of the AsyncTask, simply make a static call to your main class and set the value.
MainActivity.dataFromAsyncTask = "result blah";
I make it work by using threading and handler/message.
Steps as follow:
Declare a progress Dialog
ProgressDialog loadingdialog;
Create a function to close dialog when operation is finished.
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
loadingdialog.dismiss();
}
};
Code your Execution details:
public void startUpload(String filepath) {
loadingdialog = ProgressDialog.show(MainActivity.this, "Uploading", "Uploading Please Wait", true);
final String _path = filepath;
new Thread() {
public void run() {
try {
UploadFile(_path, getHostName(), getPortNo());
handler.sendEmptyMessage(0);
} catch (Exception e) {
Log.e("threadmessage", e.getMessage());
}
}
}.start();
}
You need to use "protocols" to delegate or provide data to the AsynTask.
Delegates and Data Sources
A delegate is an object that acts on behalf of, or in coordination with, another object when that object encounters an event in a program. (Apple definition)
protocols are interfaces that define some methods to delegate some behaviors.
Here is a complete example!!!
try this:
public class SomAsyncTask extends AsyncTask<String, Integer, JSONObject> {
private CallBack callBack;
public interface CallBack {
void async( JSONObject jsonResult );
void sync( JSONObject jsonResult );
void progress( Integer... status );
void cancel();
}
public SomAsyncTask(CallBack callBack) {
this.callBack = callBack;
}
#Override
protected JSONObject doInBackground(String... strings) {
JSONObject dataJson = null;
//TODO query, get some dataJson
if(this.callBack != null)
this.callBack.async( dataJson );// asynchronize with MAIN LOOP THREAD
return dataJson;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if(this.callBack != null)
this.callBack.progress(values);// synchronize with MAIN LOOP THREAD
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
if(this.callBack != null)
this.callBack.sync(jsonObject);// synchronize with MAIN LOOP THREAD
}
#Override
protected void onCancelled() {
super.onCancelled();
if(this.callBack != null)
this.callBack.cancel();
}
}
And usage example:
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Context _localContext = getContext();
SomeAsyncTask.CallBack someCallBack = new SomeAsyncTask.CallBack() {
#Override
public void async(JSONObject jsonResult) {//async thread
//some async process, e.g. send data to server...
}
#Override
public void sync(JSONObject jsonResult) {//sync thread
//get result...
//get some resource of Activity variable...
Resources resources = _localContext.getResources();
}
#Override
public void progress(Integer... status) {//sync thread
//e.g. change status progress bar...
}
#Override
public void cancel() {
}
};
new SomeAsyncTask( someCallBack )
.execute("someParams0", "someParams1", "someParams2");
}
Probably going overboard a bit but i provided call backs for both the execution code and the results. obviously for thread safety you want to be careful what you access in your execution callback.
The AsyncTask implementation:
public class AsyncDbCall<ExecuteType,ResultType> extends AsyncTask<ExecuteType, Void,
ResultType>
{
public interface ExecuteCallback<E, R>
{
public R execute(E executeInput);
}
public interface PostExecuteCallback<R>
{
public void finish(R result);
}
private PostExecuteCallback<ResultType> _resultCallback = null;
private ExecuteCallback<ExecuteType,ResultType> _executeCallback = null;
AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback, PostExecuteCallback<ResultType> postExecuteCallback)
{
_resultCallback = postExecuteCallback;
_executeCallback = executeCallback;
}
AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback)
{
_executeCallback = executeCallback;
}
#Override
protected ResultType doInBackground(final ExecuteType... params)
{
return _executeCallback.execute(params[0]);
}
#Override
protected void onPostExecute(ResultType result)
{
if(_resultCallback != null)
_resultCallback.finish(result);
}
}
A callback:
AsyncDbCall.ExecuteCallback<Device, Device> updateDeviceCallback = new
AsyncDbCall.ExecuteCallback<Device, Device>()
{
#Override
public Device execute(Device device)
{
deviceDao.updateDevice(device);
return device;
}
};
And finally execution of the async task:
new AsyncDbCall<>(addDeviceCallback, resultCallback).execute(device);
Hope you been through this , if not please read.
https://developer.android.com/reference/android/os/AsyncTask
Depending on the nature of result data, you should choose best possible option you can think of.
It is a great choice to use an Interface
some other options would be..
If the AsyncTask class is defined inside the very class you want to
use the result in.Use a static global variable or get() , use it from
outer class (volatile variable if necessary). but should be aware of the AsyncTask progress or should at least make sure that it have finished the task and result is
available through global variable / get() method. you may use
polling, onProgressUpdate(Progress...), synchronization or interfaces (Which ever suits best for you)
If the Result is compatible to be a sharedPreference entry or it is okay to be saved as a file in the memory you could save it even from
the background task itself and could use the onPostExecute() method
to get notified when the result is available in the memory.
If the string is small enough, and is to be used with start of an
activity. it is possible to use intents (putExtra()) within
onPostExecute() , but remember that static contexts aren't that safe
to deal with.
If possible, you can call a static method from the
onPostExecute() method, with the result being your parameter

Populate TextView on main activity form another class

I have a problem updating a TextView on my MainActivity form a class which is Async I have seen that I need to set the Context of the second class to that of the MainActivity but I don't know how to achieve this in this scenario. My app looks like this.
class RestOperation extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
//Java.net Http transaction happens here
}
#Override
protected void onPostExecute(Void result) {
//I wish to set the value of the TextView with the result here!
}
It'll be good if you will create interface which will be call at onPostExecute and at Main activity implement that interface and get your value and set value with textview.
2.newrestOperation(YourActivity.this,textviewobject).execute("yours","params","here");
So, your AsyncTask class should look like this :
Textview mtxt;
class RestOperation extends AsyncTask<String, Void, Void> {
Context _activityContext;
public RestOperation(Context activityContext,Textview txt){
this._activityContext = activityContext;
this.mtxt = txt;
}
#Override
protected String doInBackground(String... params) {
//Java.net Http transaction happens here
}
#Override
protected void onPostExecute(String result) {enter code here
mtxt .setText(yourText);
}
}
But #1 is better way.
You can do it like this :
#1 : Make a constructor for your RestOperation class to get the Context from your Activity like this :
public RestOperation(MainActivity activityContext){
this._activityContext = activityContext;
}
#2 : Pass the Activity context while initializing the AsyncTask class like this :
new RestOperation(MainActivity.this).execute("yours","params","here");
So, your AsyncTask class should look like this :
class RestOperation extends AsyncTask<String, Void, String> {
MainActivity _activityContext;
public RestOperation(MainActivity activityContext){
this._activityContext = activityContext;
}
#Override
protected String doInBackground(String... params) {
//Java.net Http transaction happens here
}
#Override
protected void onPostExecute(String result) {
((TextView)_activityContext.findViewById(R.id.yourTextViewId)).setText(yourText);
}
}
If this is in another class, you should get a reference to MainActivity through the constructor (note that I use WeakReference here so that when the activity is destroyed the onPostExecute won't be executed (because it does not need to) and the AsyncTask won't leak memory)
//first you have to change the param (the last one) to String so your doInBackground would return String
class RestOperation extends AsyncTask<String, Void, String> {
private WeakReference<MainActivity> weakRef;
public RestOperation(MainActivity activity) {
weakRef = new WeakReference<MainActivity>(activity);
}
#Override
protected String doInBackground(String... params) {
//Java.net Http transaction happens here
//You need to return some value here to set to the text view later
return "Something";
}
#Override
protected void onPostExecute(String result) {
MainActivity activity = weakRef.get();
if (activity != null) {
//activity is still alive, updates the text view
activity.updateText(result);
}
}
In your MainActivity:
new RestOperation(this).execute("Your input param");
also make another method in MainActivity:
public void updateText(String result) {
textView.setText(result);
}
Simply use:
#Override
protected void onPostExecute(String result)
{
textView.setText(result);
}
Change your code to:
class RestOperation extends AsyncTask<String, Void, Void> {
Context context;
add public RestOperation (Contex cntx) {
this.context = cntx;
}
#Override
protected Void doInBackground(String... params) { //Java.net Http transaction happens here }
#Override
protected void onPostExecute(Void result) {
//I wish to set the value of the TextView with the result here!
}
And when you cat this task
new ResrOperation(getApplicationContext()).excute();
Then you can access to items from main activity
Another choise
You can Overide onPostExecute method in your main activiry and then you will have acces to activity elemets too (In this case no context nedded)
new ResrOperation(){
#Overide
void onPostExecute(Long result) {
// access elemets from activity
}
}.excute();
First write an interface in the Async class
CompleteListener completeListener;
public void setListener(CompleteListener cmpltListnr) {
this.completeListener = cmpltListnr;
}
public interface CompleteListener {
void OnCompleteListener(String result);
}
and onPostExecute
#Override
protected void onPostExecute(Void result) {
if ( completeListener != null ) {
completeListener.OnCompleteListener(""+result);
}
}
and implement the listener in the Activity you want. and override the function
and assign this to the interface by
yourAsynClassObject.setListener(this);
#Override
public void OnCompleteListener(String result) {
textview.setText("" + result);
}

Android AsyncTask wait until finished

I am calling a web service using AsyncTask in a android app and I can not figure out how to wait until the onPostExecute has finished:
//Call Async Web Service here
AsyncCallWS task = new AsyncCallWS();
task.execute();
//Need to wait to fill this in ** Its not waiting.
String sCall = rslt;
String[] aCall = sCall.split("//|");
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
#Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "doInBackground");
GetURL();
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i(TAG, "onPostExecute");
try{
//Results HERE
rslt = resultString.toString();
}
catch(Exception ex)
{rslt = ex.toString()+ "|" + ex.toString();}
}
}
I'm not clear on what you can't/don't want to do from onPostExecute but you can use a callback if you are wanting to execute something that's not coupled to the task (so that you can run the task from anywhere)
private class OnFinishedListener {
void onFinished(String rslt);
}
private class AsyncCallWS extends AsyncTask<Void, Void, Void> {
private OnFinishedListener mAfter;
public AsyncCallWS(OnFinishedListener after) {
mAfter = after;
}
...
#Override
protected void onPostExecute(Void result) {
....
if (mAfter != null) {
//you didnt illustrate what resultString is, you might
//want this to be the returned value from doInBackground
mAfter.onFinished(resultString.toString());
}
}
}
Usage
new AsyncCallWS(new OnFinishedListener {
public void onFinished(String rslt) {
//for example
String sCall = rslt;
String[] aCall = sCall.split("//|");
}
}).execute();
You can use Tasks.await(task) in a background thread. Do not use this in UI thread. You can also set timeout for your task Tasks.await(task, 500, TimeUnit.MILLISECONDS);
Use the getStatus() method.
while (task.getStatus() != Status.FINISHED);
A better way to do this would be to call split() inside the onPostExecute() method, since onPostExecute() runs on the UI thread anyway and the while() call would block the current thread it's running in.

Errors canceling AsyncTask "Cannot make a static reference to the non-static method cancel(boolean) from the type AsyncTask<Void,Integer,Void>"

I am trying to make it so that when the user pushes a button than it cancels the Asynk task and then finishes the activity but i keep getting errors with the "MyAsyncTask.cancel(true);" if there is additional info you need please tell me.
here is what I got,
class MyAsyncTask extends AsyncTask<Void, Integer, Void>{
boolean DoingSomething;
int progress_status;
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.v("UpGradeRep", "started");
DoingSomething = true;
UpGradeRep.setVisibility(View.GONE);
UpGradeRepDis.setVisibility(View.GONE);
Toast.makeText(MainActivity.this,
"started", Toast.LENGTH_SHORT).show();
// progress_status = 0;
}
#Override
protected Void doInBackground(Void... params) {
while (!isCancelled()) {
while(DoUpCount==true){
progress_status += 1;
publishProgress(progress_status);
SystemClock.sleep(200);
if(isCancelled()){
break;
}
}
}
return null;
}
int UpGradRepcounter = 0;
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
UpGradRepcounter++;
DevUpCountDis.setText(" "+UpGradRepcounter);
Money = Money +inc;
MoneyDis.setText("$"+Money);
}
#Override
protected void onCancelled() {
Toast.makeText(getApplicationContext(), "Canceled", Toast.LENGTH_SHORT);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
DoUpCount=false;
DoingSomething = false;
Log.v("UpGradeRep", "Done");
}
}
here's what i do when i am trying to close it
Statistics.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
MyAsyncTask.cancel(true);
//^^^^Right here is where it tells me "Cannot make a static reference to the non-static method cancel(boolean) from the type AsyncTask<Void,Integer,Void>"
Intent GoToStatistics = new Intent(getApplicationContext(),statistics.class);
GoToStatistics.putExtra("LittleHelper", LittleHelper);
startActivity(GoToStatistics);
finish();
}
});
so thats the code i set up to do what i whant and it dose good but when i leave it gives a frame drop warning in my Logcat so i was ausuming that im not closeing it properly
im starting it like this
so when the user pushes the button than it starts it
UpGradeRep.setOnClickListener(new View.OnClickListener() {
#SuppressWarnings("unchecked")
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (Money>=upGM2) {
LittleHelper=true;
DoUpCount=true;
Log.v("DoUpCount"," "+DoUpCount);
(new MyAsyncTask()).execute();
}else{
Error.setText("you need more money.");
}
}
});
You're trying to call a metod over a non-static object within a static context (the onClick()) event. Basically what that error is telling you is that you must make your AsyncTask object static in order to be able to call the cancel() method over it.
This is as "easy" as declaring your AsyncTask as static, but that could generate some other compilation errors over your AsyncTask object, and you'll have to be very thorough to avoid possible memory leaks.
The method cancel(boolean mayInterruptIfRunning) (in class AsyncTask) is not a static method and you're calling it with the class name (the way static methods are invoked).
You should use the instance of MyAsyncTask to call (this):
this.cancel(true);

Android SDK - running functions in the background

I have a function which can vary in the time it takes to finish. I would like to display a progress dialog whilst this function is operating.
I am aware that you can use a 'Thread' to achieve this. Can someone point me in the right direction for doing this ?
EDIT:
Here is the code I am using:
private class LongOperation extends AsyncTask<String, Void, String>
{
ProgressDialog dialog;
public Context context;
#Override
protected String doInBackground(String... params) {
if (!dialog.isShowing())
dialog.show(); // Just in case
return null;
}
/* (non-Javadoc)
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
}
/* (non-Javadoc)
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute()
{
dialog = ProgressDialog.show(context, "Working", "Getting amenity information", true);
}
/* (non-Javadoc)
* #see android.os.AsyncTask#onProgressUpdate(Progress[])
*/
#Override
protected void onProgressUpdate(Void... values) {
// Things to be done while execution of long running operation is in progress. For example updating ProgessDialog
}
}
this is the Asnyc class. The user selects an option from the menu, and this is then executed:
longOperation.execute(""); // Start Async Task
GetAmenities(Trails.UserLocation); // Long function operation
You should use AsyncTask for this purpose. See Android developers website and How to use AsyncTask.
Some sample code:
private class LongRunningTask extends AsyncTask<Void, Boolean, Boolean> {
private ProgressDialog progress;
protected void onPreExecute() {
progress = ProgressDialog.show(yourContext, "Title", "Text");
}
#Override
protected Boolean doInBackground(Void... params) {
return true;
}
protected void onPostExecute(Boolean result) {
if(result) {
progress.dismiss();
}
}
}
Take a look at this page:
Progress Bar Reference
Greetings
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork();
}
}).start();
}
taken from here
http://developer.android.com/resources/articles/painless-threading.html

Categories