android threading with activity; - android

In my activity class i created a obj from other java file in the same package , now that the work is finished in runnable , how do i come back to my activity class from where the thread was started.
consider this situation;
public class myActivity extends activity {
MyThread t;
public void onCreate(Bundle savedInstanceState) {
t = new Mythread();
t.start();
}
}
now t is simple java class which does some background checking of data , but I dont know how to come from this t.run() method to my activity so that I can jump to another activity from there.any help is appreciated.I am new to this scenario.Thanks in advance.
Regards,
Rohit

You should consider using an AsyncTask for this.
Put in onBackground() what needs to be done in the background and in onPostExecute() what needs modify the UI.

Related

how is the onCreate() method run?

public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
When I see this basic source code in MyActivity.java,
onCreate() method is overriding just. but When I run the app, I can see that overrided method "onCreate()" runs. how is this possible?
If its possible to run the onCreate method in that code, I thought there should be a code like
onCreate();
We can always override these functions and add more to it but the Question is how are these functions called automatically when no one is calling them? We haven’t written any code to call them.
This is where the concept of CALLBACK FUNCTIONS comes in.
The concept of callbacks is to inform a class synchronous / asynchronous if some work in another class is done. Some call it the Hollywood principle: "Don't call us we call you".
Here's a example:
class A implements ICallback {
MyObject o;
B b = new B(this, someParameter);
#Override
public void callback(MyObject o){
this.o = o;
}
}
class B {
ICallback ic;
B(ICallback ic, someParameter){
this.ic = ic;
}
new Thread(new Runnable(){
public void run(){
// some calculation
ic.callback(myObject)
}
}).start();
}
interface ICallback{
public void callback(MyObject o);
}
Class A calls Class B to get some work done in a Thread. If the Thread finished the work, it will inform Class A over the callback and provide the results. So there is no need for polling or something. You will get the results as soon as they are available.
In Android Callbacks are used f.e. between Activities and Fragments. Because Fragments should be modular you can define a callback in the Fragment to call methods in the Activity. copied from here
for more study follow this link please :
link 1
link 2
The onCreate method is called during the Activity Lifecycle. The docs regarding this method state
You must implement this callback, which fires when the system first creates the activity
So the point of this method is for you to initialize anything specific to your activity that needs to be done when it is first created, and call super to propagate this to it's superclasses, allowing them to perform their initialization sequence as well. You should not be invoking this method yourself.

Is it a good practice to pass an object of Android Activity to a Thread class' constructor?

While writing an Android activity that submits input queries to a web server, I was thinking instead of having an anonymous inner class to define the networking thread, why can't we use a separate class that extends Thread.
While this works as expected, I would like to know whether this belongs any good or bad practice.
public class GreetActivity extends Activity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_greet_activity);
}
public void onClickBtn(View v){
Thread t = new WorkerThread("http://10.0.2.2:8080",this);
t.start();
}
}
class WorkerThread extends Thread{
private String targetURL;
private Activity activity;
public WorkerThread(String url, Activity act){
this.activity = act;
this.targetURL = url;
}
public void run(){
TextView tv = (TextView) activity.findViewById(R.id.textview1);
. . . . . .
}
}
Passing an Activity reference to a thread has some caveats. Activity lifecycle is separate from thread lifecycle. Activities can be destroyed and recreated e.g. by orientation change events. If the activity reference is hold in a thread, the resources held by the activity (lots of bitmap assets for example, taking a lot of memory) are not garbage collectible.
An non-static inner class also has the same problem since the reference to the parent is implicit.
A working solution is to clear the activity reference when the activity is destroyed, and supply a new activity reference when the activity is recreated.
You can only touch your UI widgets in the UI thread as mentioned by blackbelt.
For what it's worth, an AsyncTask is easier to work with than a bare-bones Thread.
In your case, no it is not, since only the UI Thread can touch the UI, your code will make your application crashes with
android.view.ViewRoot$CalledFromWrongThreadException

onCreate sometimes running in background

I'm not quite sure how to debug the phenomenon I'm currently seeing in my Android application.
I have an Activity which is just doing some networking stuff (which needs to be done in background).
This activity is launched from a PreferencesFragment using an Intent.
When the user selects the preference item, the Intent is fired and the Activity is started (then it does the networking stuff and quits using finish()).
I created an AsyncTask to perform the networking actions in the background.
(I thought that onCreate will most probably run in the UI thread...)
But then, an exception occurred:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Did onCreate() already run in the background???
To test that, I moved the networking functions directly into onCreate().
This was working well...
... at least several times.
Suddenly, an exception was thrown:
java.lang.RuntimeException: Unable to start activity ComponentInfo{...}: android.os.NetworkOnMainThreadException
Moving the code back to the AsyncTask helped... for some time.
Does anyone know why this phenomenon might occur?
Are there scenarios when onCreate() runs in the UI thread and others when onCreate() runs in background?
My class is as simple as this:
public class ReregisterInDb extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
new ReregisterAsyncTask().execute(""); // solution 1
// solution 2
//GCMFunctions gcmFunctions = new GCMFunctions(getApplicationContext());
//gcmFunctions.registerInDb();
super.onCreate(savedInstanceState);
finish();
}
class ReregisterAsyncTask extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
GCMFunctions gcmFunctions = new GCMFunctions(getApplicationContext());
gcmFunctions.registerInDb();
return null;
}
}
}
try to move the call of the method finish() of the activity in the method onPostExecute of async task
You can't do anything before calling super.onCreate(...) put that right at the beginning as I've shown below. EDIT: Also, your use of getApplicationContext in the AsyncTask is likely causing an issue, try creating a global Context variable and initializing that in onCreate and see if that works.
Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
new ReregisterAsyncTask().execute(""); // solution 1
finish();
}
class ReregisterAsyncTask extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
GCMFunctions gcmFunctions = new GCMFunctions(mContext);
gcmFunctions.registerInDb();
return null;
}
}
I finally found out the reason for this strange behavior.
I did not post the contents of the registerInDb() method.
In that method, there is a Toast:
Toast.makeText(context,
"Not currently registered with GCM. [...]",
Toast.LENGTH_LONG).show();
This message is causing the exceptions...
The solution is:
call the function in the UI thread so that the Toast messages work and
enter code heremove the AsyncTask to only cover the actual network code.
Sorry for not giving all the details. I did not think that the Toast message was the root cause.
I learned that you cannot have Toasts in AsyncTasks. The always have to run on the UI thread.

What happens to an AsyncTask when the launching activity is stopped/destroyed while it is still running?

I've seen few questions nearly identical to mine, but I couldn't find a complete answer that satisfies all my doubts.. so here I am.. Suppose that you have an activity with an inner class that extends the AsyncTask class like this:
public class MyActivity extends Activity {
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
protected Bitmap doInBackground(String... urls) {
return DownloadImage(urls[0]);
}
protected void onPostExecute(Bitmap result) {
ImageView img = (ImageView) findViewById(R.id.img);
img.setImageBitmap(result);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new DownloadImageTask().execute("http://mysite.com/image.png")
}
}
Suppose that the activity is paused or destroyed (maybe the two cases are different) while the DownloadImageTask is still running in background.. then, the DownloadImageTask's methods that run on the activity UI thread can be triggered and the DownloadImageTask may try to access Activity's methods (it is an inner class, so it can access the methods and instance variables of the outer class) with a paused or destroyed Activity, like the call to findViewByID in the example below.. what happens then? Does it silently fail? Does it produce any exception? Will the user be notified that something has gone wrong?
If we should take care that the launching thread (the Activity in this case) is still alive when running-on-UI methods are invoked, how can we accomplish that from within the AsyncTask?
I'm sorry if you find this as a duplicate question, but maybe this question is a bit more articulated and someone can answer with greater detail
Consider this Task (where R.id.test refers to a valid view in my activity's layout):
public class LongTaskTest extends AsyncTask<Void, Void, Void>{
private WeakReference<Activity> mActivity;
public LongTaskTest(Activity a){
mActivity = new WeakReference<Activity>(a);
}
#Override protected Void doInBackground(Void... params) {
LogUtil.d("LongTaskTest.doInBackground()");
SystemClock.sleep(5*60*1000);
LogUtil.d("mActivity.get()==null " + (mActivity.get()==null));
LogUtil.d("mActivity.get().findViewById(R.id.frame)==null " + (mActivity.get().findViewById(R.id.test)==null));
return null;
}
}
If I run this task from an Activity's onCreate like so:
public class Main extends Activity {
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.testlayout);
new LongTaskTest(this).execute();
finish();
}
}
No matter how long I sleep the background thread, my log always shows:
LongTaskTest.doInBackground()
mActivity.get()==null false
mActivity.get().findViewById(R.id.frame)==null false
Which is to say that the activity and its views appear to stay alive (even if I manually issue GCs via DDMS). If I had more time I'd look at a memory dump, but otherwise I don't really know why this is the case ... but in answer to your questions it appears that:
Does it silently fail? No
Does it produce any exception? No
Will the user be notified that something has gone wrong? No
The doInBackground() will keep on running even if your Activity gets destroyed(i,e your main thread gets destroyed) because the doInBackground() method runs on the worker's/background thread. There will be a 'problem' in running the onPostExecute() method as it runs on the main/UI thread and you may experience running into unrelated data but there will be no exception shown to the user. Thus, it is always better to cancel your AsyncTask when your activity gets destroyed as there is no reason to run AsyncTask when the Activity is no longer present. Use android Service if you continuously want to download something from the network even when your Component/Activity gets destroyed. Thanks.

Android, start service using thread and warn activity when it's done

I have a service which has a method that downloads an image from an URL and returns an Uri.
That service will get more complex when it has all the intended features. Therefore,
I'm invoking its methods within a thread.
My problem is how to warn the activity that the service has done it's work.
I could change a class isFinished variable but the activity had to be constantly checking
for its value.
I just want the service to tell the activity that it's work is done and the resources are
available for use.
I thought something in the lines of the service calling stopSelf() and the activity was
warned through "onServiceDisconnected" but that didn't seem very "political correct".
Thanks in advance
There are two ways to do it.
1. You can start your activity using by firing an intent.
2. You can Broadcast an intent and write receiver for it in your app when your receiver receives intent and onreceive method is called in this method you can start your activity using intent.
cheers...
public class MyActivity extends Activity{
public MyActivity() {
...
MyThread thread = new MyThread(this);
thread.start();
}
public void onFinishedThread(...) {
}
}
class MyThread extends Thread {
MyActivity activity;
public MyThread(MyActivity activity) {
this.activity = activity;
}
public void run() {
// do work
...
this.activity.onFinishedThread(...);
}
}

Categories

Resources