[Android Pro] Analysis Package Manager have died

Source: Internet
Author: User

Reference to:http://blog.csdn.net/xxooyc/article/details/50162523

This is one of the issue that was encountered today due to binder. Although it is relatively simple, keep a record of it.

Let's start by looking at crash log:

    E/hpnsservice (24810): HPNS Version is 5.0java.lang.runtimeexception:package manager have died E/hpnsservice (24810 ): At Android.app.ApplicationPackageManager.getPackageInfo (applicationpackagemanager.java:111) E/hpnsservice ( 24810): At Com.xx.xxx.util.AppUtil.checkInstalledPackageVersionCode (apputil.java:568) E/hpnsservice (24810): at Co M.xx.xxx.util.apputil.checkappstatus (apputil.java:653) E/hpnsservice (24810): at com.xx.xxx.view.applistview$ Loadingappthread.run (applistview.java:723) E/hpnsservice (24810): caused by: Android.os.TransactionTooLargeException E/hpnsservice (24810): at Android.os.BinderProxy.transactNative (Native Meth OD) e/hpnsservice (24810): at Android.os.BinderProxy.transact (binder.java:496) E/hpnsservice (24810): at Andro Id.content.pm.ipackagemanager$stub$proxy.getpackageinfo (ipackagemanager.java:1786) E/HpnsService (24810): at Android.app.ApplicationPackageManager.getPackageInfo (applicationpackagemanager.java:106) E/hpnsservice (24810): ...   3 more

Why does package manager have died occur?

Frameworks/base/core/java/android/app/applicationpackagemanager.java:

102    @Override103 Public    packageinfo getpackageinfo (String packagename, int flags) 104            throws namenotfoundexception {        try {106            packageinfo pi = mpm.getpackageinfo (PackageName, Flags, Mcontext.getuserid ()); 107            if (pi! = null) {108                return pi;109            }110        } catch (RemoteException e) {111            throw new RuntimeException ("Package manager has died", e);        113114        throw new Namenotfoundexception (PackageName);    

This is a binder call, and the reason for this is because RemoteException has occurred.


Then why do friends happen to RemoteException?

In fact, the following sentence caused By:android.os.TransactionTooLargeException caused.


Why does it cause transactiontoolargeexception?

Frameworks/base/core/jni/android_util_binder.cpp:

 682 case failed_transaction:683 Aloge ("!!!      FAILED BINDER TRANSACTION!!! ");      684//Transactiontoolargeexception is a checked exception and only throw from certain methods.        685//Fixme:transaction too large is the most common reason for failed_transaction 686//  But it isn't the only one. The Binder driver can return br_failed_reply 687//For other reasons also, such as if the Transact  Ion is malformed or 688//refers to a FD that have been closed.      We should change the driver 689//To enable us to distinguish these cases on the future. 690 jnithrowexception (env, canthrowremoteexception 691?)      "Android/os/transactiontoolargeexception" 692: "Java/lang/runtimeexception", NULL);  693 break; 


It can be seen that if the use of binder exceeds the limit of a process, the transactiontoolargeexception exception is thrown.

If other reasons cause binder crash, it will throw runtimeexception.


What is the binder memory limit for that process?

Frameworks/native/libs/binder/processstate.cpp:

#define BINDER_VM_SIZE ((1*1024*1024)-(4096))  

This is the size of the binder in a process, about 1M.

Code to allocate memory for binder:

    349#if!defined (HAVE_WIN32_IPC)        //Mmap The binder, providing a chunk of virtual address space to receive Tran Sactions.      351        Mvmstart = mmap (0, Binder_vm_size, Prot_read, Map_private | Map_noreserve, MDRIVERFD, 0);      352        if (Mvmstart = = map_failed) {      353            //*sigh*      354            aloge ("Using/dev/binder failed:unable to Mmap Transaction memory.\n ");      355            Close (MDRIVERFD);      356            mdriverfd =-1;      357        }  

Through the above cleanup, know that if the binder used in a process more than 1M, it will be crash.

And if this happens to be doing things with Getpackagemanager (), it will prompt package manager have died.


Can it be true that this is the case?

Wrote a demo to prove it:

    public class Mainactivity extends Activity {@Override protected void onCreate (Bundle savedins              Tancestate) {super.oncreate (savedinstancestate);              Setcontentview (R.layout.activity_main);          Test ();                  } private void Test () {for (int i = 0; i < 2; i++) {new Thread () {                          @Override public void Run () {int count = 0;                          list<packageinfo> list = Getpackagemanager (). Getinstalledpackages (10000);                                  for (PackageInfo info:list) {if (count >=1000) {                              Break                                          try {packageinfo pi = Getpackagemanager ()                       . Getpackageinfo (Info.packagename,                           Packagemanager.get_activities); LOG.E ("Yanchen", "Yanchen ThreadID:" +thread.currentthread (). GetId () + ", I:" + Co                              unt++);              } catch (Namenotfoundexception e) {}}}          }.start ();   }          }      }

This demo is to create two threads at a time to make binder calls.

Run the printed log:

    E/yanchen (21180): Yanchen threadid:4097,i:271      E/yanchen (21180): Yanchen threadid:4097,i:272      E/yanchen ( 21180): Yanchen threadid:4097,i:273      E/yanchen (21180): Yanchen threadid:4097,i:274      E/yanchen (21180): Yanchen threadid:4097,i:275      E/yanchen (21180): Yanchen threadid:4097,i:276  


The crash also occurs as expected at this time:

    E/javabinder (31244):!!!      FAILED BINDER TRANSACTION!!! E/androidruntime (31244): FATAL exception:thread-4798 e/androidruntime (31244): Process:com.example.testdl, pid:3124 4 E/androidruntime (31244): Java.lang.RuntimeException:Package manager have died e/androidruntime (31244): at a Ndroid.app.ApplicationPackageManager.getPackageInfo (applicationpackagemanager.java:155) e/androidruntime (31244) : At Com.example.testdl.mainactivity$1.run (mainactivity.java:40) e/androidruntime (31244): Caused by:android.os.Tr Ansactiontoolargeexception E/androidruntime (31244): at Android.os.BinderProxy.transactNative (Native Method) E /androidruntime (31244): at Android.os.BinderProxy.transact (binder.java:496) e/androidruntime (31244): at Android . Content.pm.ipackagemanager$stub$proxy.getpackageinfo (ipackagemanager.java:2208) E/AndroidRuntime (31244): at Android     Oid.app.ApplicationPackageManager.getPackageInfo (applicationpackagemanager.java:150) E/androidruntime (31244): ...   1 more D/enterprisedevicemanagerservice (3021): Ismana

How to resolve:

In fact, just avoid multiple threads at the same time to invoke the binder can be, after all, a thread will be released, so theoretically it is difficult to happen.

Modified Demo:

    Synchronized (mainactivity.class) {          packageinfo pi = Getpackagemanager ()                  . Getpackageinfo (Info.packagename,                          packagemanager.get_activities);      }  

Running again will not crash.

[Android Pro] Analysis Package Manager have died

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.