AsyncTask onPostExecute not being called - android

The project I'm working on is slightly more complicated but I made this simple test to try to track down what was wrong with my code. The progress dialog never dismisses. I had it at one point where they weren't returning null. '
public class SyncTestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new mTask(this).execute();
}
public class mTask extends AsyncTask<Void, Void, Void> {
Context mContext;
ProgressDialog progressDialog;
public mTask(Context aContext) {
mContext = aContext;
}
#Override
public void onPreExecute() {
progressDialog = new ProgressDialog(mContext);
progressDialog.setMessage("New...");
progressDialog.show();
}
#Override
public Void doInBackground(Void... params) {
return null;
}
public Void onPostExecute(Void... params) {
progressDialog.dismiss();
return null;
}
}
}

The parameters are wrong, use this:
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
return;
}

I am agree with Cesar and Shailendra answers, but still let me make little improvement over it:
#Override
protected void onPostExecute(Void result) {
if(progressDialog.isShowing())
{
progressDialog.dismiss();
}
return;
}

Missing #Override notation before onPostExecute. Also return null is not required.

Related

ProgressDialog not displaying

I have a progress dialog, I want it to show and dismiss when my method has finished executing. now, I have this:
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Downloading...");
progressDialog.show();
new Thread(new Runnable() {
#Override
public void run() {
try{
DownloadMethod(s);
progressDialog.dismiss();
}catch (Exception e){
Toast.makeText(prefs.this, "We can't reach the data...Try again", Toast.LENGTH_SHORT).show();
}
}
}).start();
My method DownloadMethod is executed but never shows the dialog.
Actually, It must be throwing an exception with progressDialog.dismiss(); call because you cannot update UI from a worker thread, instead use AsyncTask
e.g pass parameter to constructor
private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
TypeOf_S s;
public DownloadFilesTask(TypeOf_S s){
this.s = s;
}
#Override
protected Void doInBackground(Void... obj) {
DownloadMethod(s);
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
and call it like new DownloadFilesTask(s).execute();
or with generic parameter
private class DownloadFilesTask extends AsyncTask<TypeOf_S, Void, Void> {
#Override
protected Void doInBackground(TypeOf_S... obj) {
DownloadMethod(obj[0]);
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
and call it like new DownloadFilesTask().execute(s);
progressDialog.dismiss();is throwing an exception so move your code inside runOnUiThread() method like this:
runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.dismiss();
}
});
as suggested by Pavneet you can use async task as follows where AsyncTask<String, void, String> corresponds to the input type progress value and last is result value you are interested so give data types accordingly.
private class DownloadFilesTask extends AsyncTask<String, void, String> {
protected String doInBackground(String... urls) {
//here do the actual downloading instead of calling the DownloadMethod(s)
}
protected void onPreExecute() {
//here show the dialog
progressDialog.show();
}
protected void onPostExecute(String result) {
//here hide the dialog
progressDialog.dismiss();
}
}
and where you are calling the download function you just call this
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Downloading...");
new DownloadFilesTask().execute(s);
//here s is assumed to be string type you can give anything

Implement interface inside Asynctask

I don't want to implement an interface directly in asynctask class like this:
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
swipeRefreshLayout.setRefreshing(true);
}
#Override
protected Void doInBackground(Void... params) {
retrofitCallBackUtil.getLastTenMessageCallBack(AppConfig.USER_ID, userId, offsetNumber, service, new RetrofitResponseCallBack() {
#Override
public void onSuccess(ArrayList<Message> messages) {
messageAdapter.insertToTheFirst(messages);
}
#Override
public void onFailure() {
}
});
offsetNumber += 5;
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
messageAdapter.notifyDataSetChanged();
swipeRefreshLayout.setRefreshing(false);
}
}.execute();
I just to implement it by main class and put this into this parameter like this:
retrofitCallBackUtil.getLastTenMessageCallBack(AppConfig.USER_ID, userId, offsetNumber, service, this);
but I cannot do it inside asynctask method. So anyone can give me some solution?
I assume you have these code in MainActivity (or something similar).
Let's implement the interface you need to pass into getLastTenMessageCallBack in this Activity by implements RetrofitResponseCallBack {...}
Now, in your Asyntask doInBackground method, call
retrofitCallBackUtil.getLastTenMessageCallBack(AppConfig.USER_ID, userId, offsetNumber, service, MainActivity.this)
Voila, you don't have to create anonymous class inside your Asyntask anymore.
Note that, you have to move and place the fields/params properly, just the matter of being right place, no big deal :D
Create a class separately for AsyncTask like this. This AsyncTask will process the data and publish the data who implements the interface defined inside the AsyncTask . In this case interface defined is DataDownloadListener
public class GetFoldersAsync extends AsyncTask<Integer,Boolean,Boolean> {
Context context;
ProgressDialog dialog;
ArrayList mFolderDataLevel;
public GetFoldersAsync(Context context){
this.context=context;
}
public static interface DataDownloadListener {
public void dataDownloadedSuccessfully(ArrayList data);
public void dataDownloadFailed();
}
DataDownloadListener dataDownloadListener;
public void setDataDownloadListener(DataDownloadListener dataDownloadListener) {
this.dataDownloadListener = dataDownloadListener;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = ProgressDialog.show(context, "Please wait", "Processing.........");
}
#Override
protected Boolean doInBackground(Integer... params) {
Log.v(Constants.BLL_LOG, "ExplorerDBOperation doInBackground ");
mFolderDataLevel=new ArrayList();
// Process to populate mFolderDataLevel
return true;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if(dialog!=null && dialog.isShowing())
{dialog.dismiss();}
Log.v(Constants.BLL_LOG, "ExplorerDBOperation onPostExecute ");
if(mFolderDataLevel!=null && mFolderDataLevel.size()>0){
dataDownloadListener.dataDownloadedSuccessfully(mFolderDataLevel);
}else{
dataDownloadListener.dataDownloadFailed();
}
}
}
Now in the caller Activity, call this method when the AsyncTask needs to process and get back data to same activity.
public class HomeActivity extends AppCompatActivity {
//Other necessary methods goes here .....
//call this method for processing AsyncTask and to get back data
public void getFolderData(int parentID, int callerID){
Log.v(Constants.BLL_LOG,"parentID="+parentID+" , callerID="+callerID);
mCallerID=callerID;
GetFoldersAsync getFolders = new GetFoldersAsync(this);
getFolders.setDataDownloadListener(new GetFoldersAsync.DataDownloadListener()
{
#SuppressWarnings("unchecked")
#Override
public void dataDownloadedSuccessfully(ArrayList data) {
Log.v(Constants.BLL_LOG,"getFolderData dataProcessSuccessfully");
// Success data with populated ArrayList to process further
}
#Override
public void dataDownloadFailed() {
//Failure
Log.v(Constants.BLL_LOG,"getFolderData dataProcessFailed()");
}
});
getFolders.execute(callerID);
}
}

asyncTask not working for me

I have an IME service class and a long operation method in it. I want to run the LongOperation task in a asyncTask class that is in the IME Service class.
public class Myimeservice extends InputMethodService
implements KeyboardView.OnKeyboardActionListene {
//...
//some code here....
//...
public void setDictionary(){
//....
}
private class LongOperation extends AsyncTask<String, Void, String> {
private Myimeservice parent;
public LongOperation(Myimeservice pim){
parent = pim;
}
#Override
protected String doInBackground(String... params) {
Myimeservice tmp = new Myimeservice();
tmp.setDictionary();
return "Executed";
}
#Override
protected void onPostExecute(String result) {
//app.hideLoading();
}
#Override
protected void onPreExecute() {
//app.showLoading();
}
#Override
protected void onProgressUpdate(Void... values) {}
}
When i run it, the application forced to close. please help me.
I think the error is somewhere in your public void setDictionary() method.
I assume that you are manipulating a variable that is bound to the UIThread/MainThread, the application will crash since doInBackground is on another Thread.
Instead make the setDictionary() method return the dictionary and return it instead of "Executed" in doInBackground().
This will call the onPostExecute(Object result) which is run on UIThread/MainThread.
Something like this:
private class LongOperation extends AsyncTask<String, Void, Dictionary> {
#Override
protected Dictionary doInBackground(String... params) {
Myimeservice tmp = new Myimeservice();
Dictionary dict = tmp.setDictionary();
return dict;
}
#Override
protected void onPostExecute(Dictionary result) {
//do what ever you meant to do with it;
}
}
If you are not expecting any result from it you can just do:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
tmp.setDictionary();
}
});
I use the Runnable instead of AsyncTask and the problem solved.
final Runnable r = new Runnable(){
public void run(){
setDictionary();
}
};
this code is in onCreate() method of service.
Tanks a lot Tristan Richard.

Can't Override onPostExecute() method in AsyncTask Class

I know there are several question which are quite similar to this one, but they didn't helped me so far. I'm still not able to override this AsyncTasks.
Can you hel me?
I already made sure that doInBackground() devlivers some type that onPostExecute() requires (Boolean in the first and JSON in the second example).
Do you see anything except that i extend AsyncTask as raw type (was not sure about what to enter here)
This is the error eclipse tells me for each method:
The method onPostExecute(Boolean) of type Register.NetCheck must override or implement a supertype method
and for the classes eclipse tells me:
The type Register.NetCheck must implement the inherited abstract method AsyncTask.doInBackground(Object...)
AsyncTask is a raw type. References to generic type AsyncTask should be
parameterized
EXAMPLE 1:
private class NetCheck extends AsyncTask {
#Override
protected void onPreExecute(){
super.onPreExecute();
do.something();
}
#Override
protected Boolean doInBackground (String... args){
if (do.something.worked){
return true; }
else { return false}
}
#Override
protected void onPostExecute(Boolean th){
evalute.input.boolValue();
}
}
EXAMPLE 2:
private class ProcessRegister extends AsyncTask {
#Override
protected void onPreExecute() {
super.onPreExecute();
show.some.dialog();
}
#Override
protected JSONObject doInBackground(String... args) {
JSONObject json = generate.some.json();
return json;
}
#Override
protected void onPostExecute(JSONObject json) {
evaluate.something();
}
}
Your async task is not expecting a return value, so it does not recognise
protected void onPostExecute(Boolean th)
Try this instead:
private class NetCheck extends AsyncTask<String, Void, Boolean> {
#Override
protected void onPreExecute(){
super.onPreExecute();
do.something();
}
#Override
protected Boolean doInBackground (String... args){
if (do.something.worked){
return true; }
else { return false}
}
#Override
protected void onPostExecute(Boolean th){
evalute.input.boolValue();
}
}
Replace Boolean with JSONObject for the second example. Try to always use the IDE to automatically implement the methods for you, will avoid problems like this.
You should extend AsyncTask with types. See example below.
public class MyTask extends AsyncTask<Void, String, Integer> {
#Override
protected Integer doInBackground(Void... params) {
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected void onCancelled(Integer integer) {
super.onCancelled(integer);
}
#Override
protected void onCancelled() {
super.onCancelled();
}
}
Replaces Void, String, Integer with apropriate types. More info is here.
About Eclipse. Delete in and install Android Studio.

progressDialog stops to update when I rotate screen

I'm with a little problem that is driving me crazy. I'm using a AsyncTask in a retained Fragment to update a progressDialog in my activity. I'm using callbacks to send the progress from my fragment.
The problem is: When I rotate my screen it simply stops do update the progressDialog in the recreated activity. It seems like onProgressUpdate stops to being called in the rotated activity.
the relevant part of the code is shown below:
Worker Fragment
public class WorkerFragment extends Fragment {
Context mContext;
...
public static interface TaskCallbacks {
void onPreExecute();
void onProgressUpdate(int... progress);
void onPostExecute();
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallbacks = (TaskCallbacks) activity;
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain this fragment across configuration changes.
setRetainInstance(true);
}
//inner class
class DownloadFileFromURL extends AsyncTask<String, Int, Void> {
#Override
public void onPreExecute() {
if (mCallbacks != null) {
mCallbacks.onPreExecute();
}
#Override
public String doInBackground(String... f_url) {
... //some verifications of files
if(!localFile.exists()){
//http connection, check, buffer, inputstream, etc...
publishProgress((int)((bytesDownloaded*100)/remoteFileSize));
...
}
}
#Override
protected void onProgressUpdate(int... percent) {
if (mCallbacks != null) {
mCallbacks.onProgressUpdate(percent);
}
}
...
}
}
and the Activity
public class Updater extends Activity implements WorkerFragment.TaskCallbacks {
private WorkerFragment myWorker;
private ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_updater);
pDialog=null;
showDialog(1);
FragmentManager fm = getFragmentManager();
myWorker = (WorkerFragment) fm.findFragmentByTag("task");
if(myWorker == null)
{
myWorker = new WorkerFragment();
fm.beginTransaction().add(myWorker, "task").commit();
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case 1:
pDialog = new ProgressDialog(this);
pDialog.setMessage("Baixando arquivos de mídia");
pDialog.setIndeterminate(false);
pDialog.setMax(100);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setCancelable(false);
pDialog.show();
dialogType=progress_bar_type;
return pDialog;
}
}
#Override
public void onProgressUpdate(int... progress) {
//setting progress percentage
if(pDialog!=null)
{
pDialog.setProgress(progress[0]);
}
}
#Override
public void onPostExecute(){
if(pDialog!=null)
{
dismissDialog(1);
...
}
}
Try to put this code in manifest, where you've indicated your activity
android:configChanges="orientation|screenSize"

Categories

Resources