Can not use setContentView from AsyncTask - android

I'm trying to change the layout of my Activity through AsyncTask.
In onPostExecute() I'm calling:
MyActivity.this.setContentView(R.layout.activity_sub);
but it wont let me, saying "MyActivity is not an enclosing class".
Can anyone please help?

Shouldn't need the 'MyActivity.this.'; the below works for me:
public class MyAsyncTask extends AsyncTask<Void, Void, Integer> {
#Override
protected Integer doInBackground(Void... params) {
return R.layout.activity_home;
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
setContentView(result);
}
}

I think this is a wrong way to change layout in activity in rutime. If you want to show a screen with another layout you should use fragments or create another one activity and set there up your layout.

It should work if you embed the AsyncTask class as an inner class of the activity.
public class MyActivity extends Activity {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
...
public class MyAsyncTask extends AsyncTask<Void, Void, ...> {
#Override
protected ... doInBackground(Void... params) {
...
}
#Override
protected void onPostExecute(... result) {
super.onPostExecute(result);
setContentView(R.layout.activity_sub);
}
}
}

Related

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.

Call AsyncTask from another class

In an existing app I have an activity with an inner class which extends AsyncTask, this looks like the following:
public class Activity_1 extends BaseActivity {
....
new async().execute();
...
public class asyncextends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... progress) { ... }
protected void onPreExecute() { ... }
protected void onPostExecute(String result) { ... }
}
}
Now, I need to call the same doInBackground-method from another activity, but the onPostExecute() of the this inner class operates on some local UI variables and hence it's not possible to use it from outside the clas.
Is there any way I can call this AsyncTask, and just override the onPostExecute andonPreExecute-method, or shall I create yet another inner-class in the other activity, do the same background thing (of course move it to common utility-class or something), etc...?
You can make a separate abstract package private class, extending AsyncTask and implementing doInBackground() method:
abstract class MyAsyncTask extends AsyncTask<Void, Void, String> {
#Override
final protected String doInBackground(Void... progress) {
// do stuff, common to both activities in here
}
}
And in your activities just inherit from MyAsyncTask (new class probably should be private, by the way), implementing onPostExecute() and onPreExecute() methods:
public class Activity_1 extends BaseActivity {
...
new Async1().execute();
...
private class Async1 extends MyAsyncTask {
#Override
protected void onPreExecute(){
// Activity 1 GUI stuff
}
#Override
protected void onPostExecute(String result) {
// Activity 1 GUI stuff
}
}
}
If onPreExecute and onPostExecute contain some common actions as well, you can apply the following pattern:
abstract class MyAsyncTask extends AsyncTask<Void, Void, String> {
public interface MyAsyncTaskListener {
void onPreExecuteConcluded();
void onPostExecuteConcluded(String result);
}
private MyAsyncTaskListener mListener;
final public void setListener(MyAsyncTaskListener listener) {
mListener = listener;
}
#Override
final protected String doInBackground(Void... progress) {
// do stuff, common to both activities in here
}
#Override
final protected void onPreExecute() {
// common stuff
...
if (mListener != null)
mListener.onPreExecuteConcluded();
}
#Override
final protected void onPostExecute(String result) {
// common stuff
...
if (mListener != null)
mListener.onPostExecuteConcluded(result);
}
}
and use it in your activity as following:
public class Activity_1 extends BaseActivity {
...
MyAsyncTask aTask = new MyAsyncTask();
aTask.setListener(new MyAsyncTask.MyAsyncTaskListener() {
#Override
void onPreExecuteConcluded() {
// gui stuff
}
#Override
void onPostExecuteConcluded(String result) {
// gui stuff
}
});
aTask.execute();
...
}
You can also have your Activity implement MyAsyncTaskListener as well:
public class Activity_1 extends BaseActivity implements MyAsyncTask.MyAsyncTaskListener {
#Override
void onPreExecuteConcluded() {
// gui stuff
}
#Override
void onPostExecuteConcluded(String result) {
// gui stuff
}
...
MyAsyncTask aTask = new MyAsyncTask();
aTask.setListener(this);
aTask.execute();
...
}
I wrote the code from the head, so it might contain errors, but it should illustrate the idea.
Its so simple just Simply build an object of main class and than call the inner class like this
OuterMainClass outer = new OuterMainClass();
outer.new InnerAsyncClass(param)
.execute();
this answer is too late to help you but hope it help others.
Thanks
1.Create a constructor of AsynckTask in ClassOne.
2.Crate object or ClassOne by new keyword.
3.Call Async Task by object
ClassOne{
class AsyncParmas extends AsyncTask {
public ADDloadGeofenceDetails() {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... params) {
}
}
Class ClassTwo{
ClassOne obj= new ClassOne ();
obj.new AsyncParmas ().execute();
}
}
GoodLuck Who were facing problem.
If we create one static method which is in one class and and will be execute in any class in doInBackground of AsyncTask we can easily update UI through same class and even in different class .

Android - Function execute listener

Hey i don't know if that's the right way to do it but if it is how can i do it...
I have one abstact class with AsyncTask
public abstract class A{
A(){
new Task().execute();
}
public abstract void postAction();
private class Task extends AsyncTask<String, String, String>{
protected String doInBackground(String... args)
{
//smth
}
protected void onPostExecute(String file_url){
postAction();
}
}
}
After that i have class that extends A class and overrides it's postAction() method:
public class B extends A{
B(){
//smth
}
postAction(){
//some action
}
}
In my activity i have instance of B and i want to perform action when postAction is called... so i want function listener if possible and how can i do it
class C extends Activity{
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
//somethingggg happeiningggg
}
MyListener listener = new MyListener(){
onPostActionCalled()
{
//start another activity or smt :D
}
};
}
So i have class for json response(class A) and class B that extends it and overrides it's post method so i can do what i want for specific situation(expect different data or smth else nvm)
In my activity i want to perform action when class B's post method is called
I don't know if i need to do listener or handler idk at all....
Stefan is right, why complicate things?
See this real simple example of threading:
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new MyTask(new TaskListener() {
#Override
public void finished(boolean result) {
// back on main thread after task finishes
}
}).execute();
}
private interface TaskListener{
void finished(boolean result);
}
private class MyTask extends AsyncTask<Object, Integer, Boolean>{
private TaskListener mListener;
public MyTask(TaskListener mListener) {
super();
this.mListener = mListener;
}
#Override
protected Boolean doInBackground(Object... params) {
// long running background operation
return true;
}
#Override
protected void onPostExecute(Boolean result) {
mListener.finished(result);
super.onPostExecute(result);
}
}
}

onPostExecute() can't use MainActivity elements

I have doInBackground(). after function I want to change some TextView on MainActivity.
but When I trigger the function on main activity I got NullPointerException on TextView line.
protected String doInBackground(Object... arguments) {
some code..
return result;
}
#Override
protected void onPostExecute(String result) {
if(result!=null)
new MainActivity().setScoreListUpdate(result);
}
MainActivity:
public void setScoreListUpdate(String settings)
{
String[] yeniscore = settings.split("\\|");
if(yeniscore.length > 1)
{
birinci.setText(yeniscore[1]); << NULLPOINTEREXC.
}
}
The reason this gives a NullPointerException is that you create a new instance of MainActivity instead of working on your existing one.
What you need to do is pass a reference to your Activity to the AsyncTask and then call your method on that reference.
So in your AsyncTask-class you will have a variable:
private MainActivity myMainActivity;
Add a constructor to your AsyncTask-class:
public MyAsyncTaskClassName( MainActivity activity ) {
myMainActivity = activity;
}
Then in onPostExecute you do:
myMainActivity.setScoreListUpdate(result);
Use
MainActivity.this.setScoreListUpdate(result);
instead of
new MainActivity().setScoreListUpdate(result);
in yout postExecute method.
Also, TextView called birinci should be a field in your MainActivity class, not just a variable in the onCreate method for example.
EDIT: It works like this in my program. Check out the differences.
public class DeviceSettingsStatsActivity extends ListActivity {
AsyncTask<Void, Integer, ListAdapter> task = null;
ListAdapter listAdapter = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
task = new ComputeTask().execute();
}
protected void viewComputeResult(ListAdapter result) {
setListAdapter(result);
}
private class ComputeTask extends AsyncTask<Void, Integer, ListAdapter> {
#Override
protected ListAdapter doInBackground(Void... params) {
// some stuff
}
#Override
protected void onPostExecute(ListAdapter result) {
DeviceSettingsStatsActivity.this.viewComputeResult(result);
}
}
}

Finish the calling activity when AsyncTask completes

My calling activity:
public class Hello extends Activity {
public void onCreate(Bundle savedInstanceState) {
MyTask mt = new MyTask(this);
mt.execute();
}
Now In MyTask (an external class):
public class MyTask extends AsyncTask<Void, Void, Void> {
private Context mContext;
public MyTask(Context context) {
mContext = context;
}
//doinbackground, etc
protected void onPostExecute() {
mContext.finish();
}
Other things are working as expected if I remove mContext.finish() above.
But if I'm calling mContext.finish() , I'm getting an error: The method finish() is undefined for the type Context (Eclipse doesn't show finish() when I write mContext. so that suggests I'm using finish() wrongly.)
What do I need to do to finish the calling activity Hello after MyTask completes the task
((Activity)mContext).finish();
Would be the correct way to cast a Context to an Activity and call its finish() method. Not sure why you'd want to finish an Activity from an AsyncTask though
What you can try to do instead of calling context.finish(), why don't you do a callback interface like this:
public interface TaskCallback{
void done();
}
Then you implement this into your Activity
public Hello extends Activity implements TaskCallback{
.....BUNCH OF ACTIVITY CODE.....
public void onCreate(Bundle savedInstanceState) {
MyTask mt = new MyTask(this);
mt.execute();
}
public void done() {
finish();
}
}
And instead of having Context as a parameter you have TaskCallback
public class MyTask extends AsyncTask<Void, Void, Void> {
private TaskCallback mCallback;
public MyTask(TaskCallback callback) {
mCallback = callback;
}
//doinbackground, etc
protected void onPostExecute() {
mCallback.done();
}
There you go, it gives you more flexibility to custom each implementation.
I got the same situation, then I do as follows:
public class MyTask extends AsyncTask<Void, Void, Void> {
private Activity mActivity;
private Context mContext;
public MyTask(Activity activity) {
mActivity = activity;
mContext = mActivity.getApplicationContext();
}
//doinbackground, etc
protected void onPostExecute() {
mActivity.finish();
}
Hope it help :)
Define a method in your activity class like this:
public void FinishAfterAsyncTask()
{
this.finish();
}
And call this method from the OnPostExecute method of the AsynTask class.
You could create a new private AsyncTask extended from your public one.
In this private AsyncTask you have access to the Activity stuff and you can override the onPostExecute method to finish it.
Your truly AsyncTask
public class MyPublicAsyncTask extends AsyncTask<Void, Void, Void> {
Context context;
public GetHorariosAsyncTask(Context ctx){
context = ctx;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// prepare yourself for an async work
}
#Override
protected Void doInBackground(Void... params) {
// Do yout cool async stuff
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// you're finish, let's tell to user
}
}
Your Activity with private AsyncTask
public class MyActivity extends Activity {
Activity mAct;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mAct = this;
}
private class MyPrivateAsyncTask extends MyPublicAsyncTask {
public MyPrivateAsyncTask(Context ctx) {
super(ctx);
// TODO Auto-generated constructor stub
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// our async task is completed! let's take care of this activity
mAct.finish();
}
}
}
Can you try
this.finish()
Seems like its because of calling it using mContext that it says undefined.

Categories

Resources