Android AsyncTask errors with onPostExecute - java

i have a question regarding the AsyncTask class in android, and why it is giving me an error. I have defined an inner class here..
class MyTask extends AsyncTask<String,String,Integer>{
Context context;
ProgressDialog dialog;
MyTask(Context c)
{
this.context = c;
}
//#Override
protected void onPreExecute()
{
dialog = new ProgressDialog(context);
dialog.setMessage("Scanning Ports!");
dialog.show();
}
#Override
protected Integer doInBackground(String... params) {
// TODO Auto-generated method stub
for(intBeg = intBeg; intBeg <= intEnd; intBeg++
{
try
{
Socket s = new Socket(strMachine, intBeg);
isConnected += strMachine + " Is Listening On Port: " + intBeg + "\n";
Log.d("PORTSCAN", isConnected);
s.close();
}catch(Exception e){
notConnected += strMachine + " Is Not Listening On Port: " + intBeg + "\n";
//Toast.makeText(getBaseContext(), e.getMessage(), 3000).show();
Log.d("PORTSCAN", notConnected);
}
}
return 1;
}
protected void onPostExecute(Integer... params)
{
}
protected void onProgressUpdate(String... params)
{
}
}
However, when the doInBackground finishes, it supposed to call onPostExecute(), which never happens. And even when i try to use the "#Override" annotation over the onPostExecute(), it gives me an error saying onPostExecute must override a superclass method. I dont get what is happening! any help? Thanks!

onPostExcecute(Integer result) takes a single argument (no ...).
If the arguments don't match, it will not match the super method and will therefore not override it (and be called). Generally if #Override gives you an error something is wrong with your method name/parameters (or the superclass does not have such a method).

protected void onPostExecute(Integer params)//its single Integer object, not array of Integer objects
its java Varargs.and you can't change parameter of overrided method,You just change the Behaviour of override method.And its method of AsyncTask Class.

Just use this onPostExecuteMethod
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
Log.e("LOG", " on Post");
}

Check this code
private class DownloadingProgressTask extends
AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog = new ProgressDialog(ShowDescription.this);
/** progress dialog to show user that the backup is processing. */
/** application context. */
protected void onPreExecute() {
this.dialog.setMessage("Please wait");
this.dialog.show();
}
protected Boolean doInBackground(final String... args) {
try {
downloadFile(b.getString("URL"));
return true;
} catch (Exception e) {
Log.e("tag", "error", e);
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (success) {
Toast.makeText(ShowDescription.this,
"File successfully downloaded", Toast.LENGTH_LONG)
.show();
imgDownload.setVisibility(8);
} else {
Toast.makeText(ShowDescription.this, "Error", Toast.LENGTH_LONG)
.show();
}
}
}

Related

Get AsyncTask's result without blocking the thread

I have the code that sends requests to REST API in AsyncTask.
Also, I have a ProgressDialog initialization in preExecute() and its dismission in postExecute().
I want ProgressDialog to show an indeterminate spinner (you know, that loading animation), but I need to get a result too. get() blocks the main thread where I'm invoking it in - what's the workaround for that case?
Main thread (main activity)
LoginTask task_login = new LoginTask();
AsyncTask<String, Void, JSONObject> response = task_login.execute(et_username.getText().toString(), et_password.getText().toString());
try {
JSONObject json = response.get();
Toast.makeText(MainActivity.this, json.toString(), Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
Toast.makeText(MainActivity.this, "Interrupted.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
AsyncTask (dummy doInBackground):
public class LoginTask extends AsyncTask<String, Void, JSONObject> {
private LoginTask self = this;
private ProgressDialog progressDialog;
#Override
protected JSONObject doInBackground(String... params) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(MainActivity.context,
"Logging in...", "");
progressDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
MainActivity.context.getResources().getResourceEntryName(R.string.dialog_button_cancel), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
self.cancel(true);
}
});
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
progressDialog.dismiss();
}
}
You can use AsyncTask's onProgressUpdate() method to perform the actions on the UI thread (such as showing or updating a loading animation) while doInBackGround() does the background work on another thread.
Basically you invoke the publishProgress() method from within doInBackGround(), which in turn calls onProgressUpdate().
Check out the Android reference page on AsyncTask for an example.
Please look at the usage of AsyncTask https://developer.android.com/reference/android/os/AsyncTask#usage
There is a callback function onPostExecute which returns (as parameter) the value you requested:
private class RestTask extends AsyncTask<Object, Object, String> {
protected String doInBackground(Object... args) {
// this happend on background thread
return downloadData();
}
protected void onPreExecute() {
// this happend on UI thread
showSpinner();
}
protected void onPostExecute(String result) {
// this happend on UI thread
hideSpinner();
doSomethingWithDownloadResult(result);
}
}
Usage:
new RestTask().execute()
As you edited the question, this:
try {
JSONObject json = response.get();
Toast.makeText(MainActivity.this, json.toString(), Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
Toast.makeText(MainActivity.this, "Interrupted.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
should be called in previous Tasks onPostExecute method, this way you will not block you UI with get method waiting on login result.
1 - You can use a callback method.
but keep in mind you should call it in your main thread.
2 - you can use LocalBroadcastManager in order to send your result through Intent.
3 - you might want to use in application messaging libraries which are more reliable in my opinion. one example which I use very often is EventBus.

onPostExecute is not called

So I am having issues with my AsyncTask. I need postExecute to display an alert dialog if a certain error throwable is caught in doInBackground. The problem is that postExecute is never called. I have tried adding #Override but Android Studio says that it isn't overriding a method in its super class. I have also tried changing the return type. I looked around this site and couldn't find an answer. Thanks in advance.
AsyncTask Class
public class AsyncTaskActivity extends AsyncTask<Void, Void, Void> {
String exception;
#Override
protected void onPreExecute() {
}
protected void onPostExecute() {
if (exception.contains("java.net.UnknownHostException")) {
MainActivity.showDialog();
Log.i("Error Message", "ERROR MESSAGE SHOWN");
}
}
#Override
protected Void doInBackground(Void... params) {
try {
Log.i("AsyncTask", "Loading...");
// Make a URL to the web page. This takes the string representation of the URL
// and changes it into a URL object
URL url = new URL("http://api.wunderground.com/api/0c0fcc3bf62ab910/conditions/q/IN/Fort_Wayne.json");
// Get the input stream through URL Connection
URLConnection con = url.openConnection();
InputStream is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
// read each line and write to text file
while ((line = br.readLine()) != null) {
Log.i("AsyncTask", line);
TextEditor.file = new File(MainActivity.path, "siteInfo.txt");
TextEditor.writeString(line);
}
TextEditor.saveAndClose();
} catch (Exception e) {
e.printStackTrace();
exception = e.toString();
}
Log.i("AsyncTask", "DONE");
return null;
}
}
showDialog method
public static void showDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.context);
builder.setView(R.layout.dialog_layout);
builder.setPositiveButton(
R.string.dialog_close,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
System.exit(1);
}
});
builder.show();
}
look like you're missing something
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (exception.contains("java.net.UnknownHostException")) {
MainActivity.showDialog();
Log.i("Error Message", "ERROR MESSAGE SHOWN");
}
}
First please refer this documentation. you have missed parameters on onPostExecute().
https://developer.android.com/reference/android/os/AsyncTask.html
What you would have to do is,
#Override
protected void onPostExecute(Params) {
// your logics
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (exception.contains("java.net.UnknownHostException")) {
MainActivity.showDialog();
Log.i("Error Message", "ERROR MESSAGE SHOWN");
}
}
Please note that you need to initialize exception, otherwise it may cause a NullPointerException

How to let Async Task finish in Android

I'm working on an app that retrieves data from network, stores them to the device and then reads them.
Problem is, I get my data in a Async Task.. And my app doesn't let the task finish before trying to show the data to the user..
I've tried task.get() but without result (it just stops there).
Here is my task:
public GetOptionsTask(XMLPortalGetOptions request) {
super(request);
}
protected void onCancelled(){
// TODO afficher message pas d'options sur le disque
}
#Override
public void handleError(Transaction transaction) {
// TODO afficher message pas d'options sur le disque
}
#Override
public void handleSuccess(Transaction transaction) {
saveOptions(transaction.getResponse());
request = null;
Log.d(OptionsManager.class.getName(), this.getStatus().toString());
}
This task is an instance of my custom Async Task:
protected BaseXMLTransaction request;
public abstract void handleError(Transaction transaction);
public abstract void handleSuccess(Transaction transaction);
public TransactionTask(BaseXMLTransaction request){
this.request = request;
}
#Override
protected Void doInBackground(Void... params) {
try {
Log.i(TransactionTask.class.getName(), "Doing in background");
SocketHandler.sendTransaction(this, request.getRequest());
} catch (SocketHandlerNotConfiguredException e) {
Log.e(TransactionTask.class.getName(), "SocketHandler's parameters were not set.");
}
return null;
}
#Override
public void transactionResult(Transaction transaction) {
switch (transaction.getCode()) {
case ERROR:
Log.e(TransactionTask.class.getName(), "ERROR !!!");
handleError(transaction);
break;
case NO_CLIENT:
Log.e(TransactionTask.class.getName(), "No Client Error");
handleError(transaction);
break;
case NO_SERVER:
Log.e(TransactionTask.class.getName(), "No Server Error");
handleError(transaction);
break;
case OLD_VERSION:
Log.e(TransactionTask.class.getName(), "Old Version");
handleError(transaction);
break;
case TIMEOUT:
Log.e(TransactionTask.class.getName(), "Transaction Timeout");
handleError(transaction);
break;
case SUCCESS:
Log.i(TransactionTask.class.getName(), "Transaction Success");
handleSuccess(transaction);
}
}
I seriously don't know what to do... Execute goes to fast and get doesn't do anything since I'm not returning anything I guess.
onPostExecute(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.
#Override
protected void onPostExecute(String result) {
}
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
and call it like this:
new DownloadFilesTask().execute(url1, url2, url3);
I use an interface as a delegate to do this. Here is an example:
In my main activity I have a onClick listener to trigger my async call and a listener to process once the call is complete.
private void enableLocationButton(){
locationButton = (Button) findViewById(R.id.locationButton);
locationButton.setEnabled(true);
locationButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, selectLocationActivity.class);
intent.putExtra("serverURL",server.getWebServerAddressField());
startActivityForResult(intent, 200);
}
});
}
#Override
protected void onActivityResult(int requestCode,int resultCode, Intent data){
if(resultCode == RESULT_OK) {
switch (requestCode){
case 100:
processServerResponse((PmsWebServer) data.getBundleExtra("server").get("server"));
break;
case 200:
processLocationResponse((PmsDataSource)data.getBundleExtra("location").get("location"));
default:processError();
}
}else{
processError();
}
}
Somewhere in the selectLocationActivity I have a call to the Async call and something to process the response, please note that this class implements an interface that is used in the Async call.
public class selectLocationActivity extends ListActivity implements SoapServiceInterface{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_select);
chosenServer = this.removeURLHeader(getIntent().getStringExtra("serverURL"));
this.retrieveLocationOptionsByServer(chosenServer);
}
private void retrieveLocationOptionsByServer(String server) {
Map<String,Object> parms = new HashMap<String,Object>();
parms.put(WEB_SERVER_NAME,server);
SoapServiceObject service = new SoapServiceObject(Services.SERVICE_DETAILS,parms);
callTheService(service);
}
private void callTheService(SoapServiceObject service){
SoapServiceHelper helper = new SoapServiceHelper();
helper.delegate = thisActivity;
helper.execute(service);
}
#Override
public void serviceCallComplete(SoapObject response){
this.createClickableListOnScreen(response);
}
//...more code...//
}
serviceCallComplete is kicked off by the asyncTask. Below is the code for that task
public class SoapServiceHelper extends AsyncTask<SoapServiceObject, Void, SoapObject>{
public SoapServiceInterface delegate = null;
private Integer RETRY_COUNT = 0;
private final Integer MAX_RETRY_COUNT = 2;
protected SoapObject doInBackground(SoapServiceObject... args){
SoapServiceObject service = args[0];
try{
service.callTheService();
}catch(Exception e){
System.out.println("An error occurred calling the service\n" + e.getMessage());
}
return service.getResponse();
//return callDateTimeService();
}
protected void onPostExecute(SoapObject result){
delegate.serviceCallComplete((SoapObject)(result.getProperty(0)));
}
}
And finally here is the interface
public interface SoapServiceInterface {
public void serviceCallComplete(SoapObject response);
}
I know I'm displaying something to the screen directly from my result, just sub that part with a save and read ;)
One thing with that task was that it was saving stuff into a singleton. I managed to call the methods using the information from the network saved in the singleton at the onResume(). When the threads end, it goes to the onResume and everything works fine!

AsyncTask not showing dialog during operation

The progressDialog of my AsyncTask not showing. It seems correct but it doesn't display the dialog.. The operations inside works perfectly but seems ignoring the onPreExecute() and onPostExecute() methods..
private class copyApk extends AsyncTask<Void, Void, Void> {
int appPosition;
ProgressDialog mProgressDialog = new ProgressDialog(getActivity());
#Override
protected void onPreExecute(Void pre) {
super.onPreExecute();
mProgressDialog.setTitle("Copy apk");
mProgressDialog.setMessage("Copying...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... apks) {
final File customfolder = new File(Environment.getExternalStorageDirectory().toString()+File.separator+"HazyApkBackup");
if(!customfolder.exists()){
customfolder.mkdirs();
}
try
{
vacca = getActivity().getPackageManager().getApplicationInfo(app.getPackageName(), packageManager.GET_META_DATA).sourceDir.toString();
//Toast.makeText(getActivity(), "Boh "+vacca, Toast.LENGTH_SHORT).show();
process = Runtime.getRuntime().exec("cp " + vacca + " " + customfolder);
//Toast.makeText(getActivity(), "Apk copied in "+customfolder, Toast.LENGTH_SHORT).show();
}
catch (PackageManager.NameNotFoundException | IOException e)
{
Toast.makeText(getActivity(), "Sorry, the apk was not copied correctly", Toast.LENGTH_SHORT).show();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if(mProgressDialog.isShowing())
Toast.makeText(getActivity(), "Apk copied in "+customfolder, Toast.LENGTH_SHORT).show();
mProgressDialog.dismiss();
}
}
Thanks
Your onPreExecute() method isn't getting called, as it has the incorrect signature. The correct method has no parameters.
#Override
protected void onPreExecute()
{
...
The prototype of onPreExecute() :
#Override
protected void onPreExecute() {
}
The onPreExecute() and onPostExecute() methods are called on the UI thread. It is always better to use a WeakReference to avoid exceptions in future.
In your AsyncTask, create a WeakReference like :
private WeakReference<MyActivity> myWeakContext;
Then in your onPreExecute(),
MyActivity activity = this.myWeakContext.get();
ProgressDialog mProgressDialog = new ProgressDialog(activity);

Android AsyncTask's onProgressUpdate not working

I have an AsyncTask in a class. I want it to display the progress while it is getting executed. But it is not printing the Logs.
private void registerBackground() {
new AsyncTask<Void, Integer, String>() {
#Override
protected String doInBackground(Void... params) {
Log.v("TAGGG", "IN doInBackground");
msg = "Error: ";
return msg;
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
Log.v("TAGGG", "Progress: " + progress[0] + "%");
}
#Override
protected void onPostExecute(String msg)
{
Log.v("TAGGG", msg);
}
}.execute();
}
You have to use the publishProgress() method: http://developer.android.com/reference/android/os/AsyncTask.html#publishProgress(Progress...)
This method can be invoked from doInBackground(Params...) to publish
updates on the UI thread while the background computation is still
running. Each call to this method will trigger the execution of
onProgressUpdate(Progress...) on the UI thread.
onProgressUpdate(Progress...) will note be called if the task has been
canceled.
#Override
protected String doInBackground(Void... params) {
Log.v("TAGGG", "IN doInBackground");
msg = "Error: ";
int i = 0;
while (i <= 50) {
try {
Thread.sleep(50);
publishProgress(i);
i++;
}
catch (Exception e) {
Log.i(TAGGG, e.getMessage());
}
}
return msg;
}

Categories

Resources