One application has only one thread
By default, it is more accurate to say that there is only one thread in a process, which is consistent with other languages, such as C/c++,java. That means there's only one thread in the Android application, and all the components are running in one thread!
When the application starts, the system creates a process for it, and it creates a thread named Main, the creation of all its owning components, the handling of system events, the system's callbacks, and so on. All applications related things run in this thread called Main. This thread is the usual main thread (main thread). It is also known as UI thread, because only the main thread can manipulate UI-related things, so some people refer to the main thread as a UI thread, but that's not the right thing to say, because the thread that the service belongs to can also manipulate toast, but the service doesn't have a UI. Why is a non-primary thread unable to manipulate the UI? Because a system callback is often raised for UI operations, allowing a third thread to operate may cause a system callback disorder to disrupt the entire frame's timing!
The special note here is that all components in the same process are running in the same thread, and Activiy,service,boradcastreceiver and ContentProvider are running in the main threads.
The most misleading thing about service, documentation and common sense is that service is put in the background for operating time-consuming operations, but in reality, if you do time-consuming operations in the service, it will also trigger the infamous ANR (application not Responding). So if you want to use service as a server, you must create a worker thread with handlerthread or thread in the service!
The activity is also the same, you startactivity (), you open a new action, but they are all running in the same thread, so you still can not do in the original work of time-consuming operation! That is, after invoking StartActivity () to open a new activity, or to do time-consuming operations in OnPause (), OnStop (), OnDestroy (), can cause ANR.
The same is true for ContentProvider, if you are in the same process as other components, then the method of calling Contentresolver is equivalent to calling ContentProvider directly. If it is in another process, although it is through IPC, but also synchronous, because IBinder synchronization, that is, call Contentresolver will suspend the caller's process, wait for ContentProvider process to end, and then pass the result to the caller process! Therefore, if there are time-consuming operations in the ContentProvider, or in conjunction with the lock database, you must also pay attention to the occurrence of ANR!
so be sure to remember that a process has only one thread and all components run in the main thread.
Therefore, if there is a time-consuming operation, you must create a worker thread!
instance
Here's a small example of an application with five components: 2 activity, one service, one contentprovider and one broadcastreceiver. In each component's method has the printing belongs to the thread information, moreover for Activity,service and ContentProvider if does the time-consuming operation can cause the ANR, to Broadcastreceiver is so, this everybody understands!
Copy Code code as follows:
public class Activitydemo extends activity {
private static final String TAG = "Activitydemo";
Private Handler Mmainhandler = new Handler (new Handler.callback () {
public boolean handlemessage (msg) {
Dumpthreadinfo ();
return false;
}
});
@Override
protected void OnCreate (Bundle savedinstancestate) {
Dumpthreadinfo ();
Super.oncreate (savedinstancestate);
Add four buttons
LinearLayout layout = new LinearLayout (Getapplication ());
Layout.setorientation (linearlayout.vertical);
Button StartService = New button (Getapplication ());
Startservice.settext ("Start a Service");
Startservice.setonclicklistener (New View.onclicklistener () {
public void OnClick (View v) {
Intent i = new Intent (Getapplication (), servicedemo.class);
StartService (i);
}
});
Layout.addview (StartService);
Button Startanother = New button (Getapplication ());
Startanother.settext ("Start Another Activity");
Startanother.setonclicklistener (New View.onclicklistener () {
public void OnClick (View v) {
Intent i = new Intent (Getapplication (), anotheractivity.class);
StartService (i);
}
});
Layout.addview (Startanother);
Button Startcontentprovider = New button (Getapplication ());
Startcontentprovider.settext ("Start a ContentProvider");
Startcontentprovider.setonclicklistener (New View.onclicklistener () {
public void OnClick (View v) {
Getcontentresolver (). query (Contentproviderdemo.content_uri, NULL, NULL, NULL, NULL);
}
});
Layout.addview (Startcontentprovider);
Button Startreceiver = New button (Getapplication ());
Startreceiver.settext ("Start a Broadcastreceiver");
Startreceiver.setonclicklistener (New View.onclicklistener () {
public void OnClick (View v) {
Intent i = new Intent ("Android.action.start_broadcastreceiver_demo");
Sendbroadcast (i);
}
});
Layout.addview (Startreceiver);
Setcontentview (layout);
Mmainhandler.sendemptymessagedelayed (0, 500);
}
public void Dumpthreadinfo () {
Thread.dumpstack ();
LOG.E (TAG, Thread.CurrentThread (). toString ());
LOG.E (TAG, "" + Getmainlooper ());
}
}
Copy Code code as follows:
public class Anotheractivity extends activity {
private static final String TAG = "anotheractivity";
Private Handler Mmainhandler = new Handler (Getmainlooper (), new Handler.callback () {
public boolean handlemessage (msg) {
This would cause ANR
LOG.E (TAG, "You know what the is very slow slow slow slow");
Systemclock.sleep (20 * 1000);
Dumpthreadinfo ();
return false;
}
});
@Override
protected void OnCreate (Bundle savedinstancestate) {
Dumpthreadinfo ();
Super.oncreate (savedinstancestate);
Settitle ("This is another activity");
Mmainhandler.sendemptymessagedelayed (0, 500);
}
@Override
protected void OnDestroy () {
Dumpthreadinfo ();
Super.ondestroy ();
}
public void Dumpthreadinfo () {
Thread.dumpstack ();
LOG.E (TAG, Thread.CurrentThread (). toString ());
LOG.E (TAG, "" + Getmainlooper ());
}
}
Copy Code code as follows:
public class Servicedemo extends Service {
Private Handler Mmainhandler = new Handler (new Handler.callback () {
public boolean handlemessage (msg) {
This'll cause ANR, too
LOG.E (TAG, "This are very slow you know, slow slow");
Systemclock.sleep (20 * 1000);
Dumpthreadinfo ();
return false;
}
});
private static final String TAG = "Servicedemo";
@Override
Public IBinder Onbind (Intent arg0) {
Dumpthreadinfo ();
return null;
}
@Override
public void OnCreate () {
Dumpthreadinfo ();
Super.oncreate ();
Mmainhandler.sendemptymessagedelayed (0, 500);
}
@Override
public int Onstartcommand (Intent Intent, int flags, int startid) {
Dumpthreadinfo ();
Return Super.onstartcommand (Intent, flags, Startid);
}
public void Dumpthreadinfo () {
Thread.dumpstack ();
LOG.E (TAG, Thread.CurrentThread (). toString ());
LOG.E (TAG, "" + Getmainlooper ());
}
}
Copy Code code as follows:
public class Contentproviderdemo extends ContentProvider {
public static final Uri Content_uri = Uri.parse ("content://com.hilton.effectiveandroid.app/content");
private static final String TAG = "Contentproviderdemo";
@Override
public int Delete (Uri arg0, String arg1, string[] arg2) {
Dumpthreadinfo ();
return 0;
}
@Override
Public URI insert (URI uri, contentvalues values) {
Dumpthreadinfo ();
return null;
}
@Override
public Boolean onCreate () {
Dumpthreadinfo ();
return false;
}
@Override
Public Cursor query (URI uri, string[] projection, string selection, string[] Selectionargs, string sortOrder) {
Dumpthreadinfo ();
It would cause ANR of course
LOG.E (TAG, "This are very slow, you know that");
Systemclock.sleep (20 * 1000);
return null;
}
@Override
public int update (URI uri, contentvalues values, String selection, string[] Selectionargs) {
Dumpthreadinfo ();
return 0;
}
public void Dumpthreadinfo () {
Thread.dumpstack ();
LOG.E (TAG, Thread.CurrentThread (). toString ());
}
@Override
Public String GetType (Uri arg0) {
return null;
}
}
Copy Code code as follows:
public class Broadcastreceiverdemo extends Broadcastreceiver {
private static final String TAG = "Broadcastreceiverdemo";
@Override
public void OnReceive (context context, Intent Intent) {
LOG.E (TAG, "intent is" + intent);
Dumpthreadinfo ();
}
public void Dumpthreadinfo () {
Thread.dumpstack ();
LOG.E (TAG, Thread.CurrentThread (). toString ());
}
}