Strictmode Vmpolicy Demo Introduction

Source: Internet
Author: User
Tags sqlite static class throwable
1. Background introduction:

In the system monkey test and case test, we found in Dropbox a large number of Strictmode rigorous mode of error, in order to enhance the stability of the system, we intend to the project early on these types of errors to the development, to solve. This article has written a strictmode (Vmpolicy) type of demo for everyone to rough rough understanding of Strictmode. 2. Strictmode Detailed:

Strictmode is a strategic way for you to customize what you need to check for problems. There are two main policies, one time thread-side policy-(threadpolicy) and one VM-side strategy (Vmpolicy).
Threadpolicy is primarily used to discover whether there are read and write disk operations in the UI thread, whether there are network operations, and whether custom code invoked in the UI thread is performing slower.
Vmpolicy, mainly used to identify memory problems, such as activity memory leaks, SQL object memory leaks, resources not freed, able to limit the maximum number of objects for a class. 3. Strictmode (vmpolicy) The default check error type mainly has the following five kinds can be freely combined:

. Detectall ()
. Detectactivityleaks ()
. Detectfileuriexposure ()
. Detectleakedclosableobjects ()
. Detectleakedregistrationobjects ()
. Detectleakedsqlliteobjects () 4.StrictMode (Vmpolicy) The following three types of punishments can be freely combined:

. Penaltydropbox ()
. Penaltydeath ()
. Penaltylog () 5. The five error types of the above check are now written, with the following interface:

6. The main code is described below:

Import Java.io.File;
Import Java.io.FileWriter;
Import java.io.IOException;
Import java.util.ArrayList;

Import java.util.List;
Import Android.annotation.SuppressLint;
Import android.app.Activity;
Import Android.content.ContentResolver;
Import Android.content.ContentUris;
Import android.content.ContentValues;
Import Android.content.Context;
Import Android.content.IntentFilter;
Import Android.database.Cursor;
Import Android.net.Uri;
Import Android.os.Bundle;
Import android.os.Environment;
Import Android.os.Handler;
Import Android.os.Message;
Import Android.os.StrictMode;
Import Android.os.SystemClock;
Import android.provider.Contacts;
Import Android.provider.ContactsContract;
Import Android.provider.ContactsContract.Data;
Import android.provider.ContactsContract.RawContacts;
Import Android.provider.ContactsContract.CommonDataKinds.Email;
Import Android.provider.ContactsContract.CommonDataKinds.Phone;
Import Android.provider.ContactsContract.CommonDataKinds.StructuredName; Import AndroiD.text.textutils;
Import Android.util.Log;
Import Android.view.View;
Import Android.widget.Button;

Import Android.widget.TextView; @SuppressLint ("Handlerleak") @SuppressWarnings ("Deprecation") public class Strictmodedemo extends Activity implements
    View.onclicklistener {private static final String TAG = "strictmodeactivity";
    Private static Final Boolean Debug_mode = true;

    private static final int msg_get_data_ok = 100;
    Private Context Mcontext;
    Private TextView Mtextview;
    Private Button Mcursorleakbutton;
    Private Button Mclosableleakbutton;
    Private Button Mactivityleakbutton;
    Private Button Mregistrationsleakbutton;

    Private Button Mclassinstancelimitbutton;
    Private Thread mthread = null;
    Private Teststrictmodebroadcast mreceiver = null;

    Private list<classcounts> mclasslist = new arraylist<strictmodedemo.classcounts> (); private static Class classcounts{/**no Content, only used test!*/} private HaNdler Mhandler = new Handler () {@Override public void Handlemessage (Message msg) {switch (ms
                    G.what) {case msg_get_data_ok:string result = (String) msg.obj; if (result) {result = "Sorry, the phone has no contact textutils.isempty."
                    ";
                } mtextview.settext (Result);
            Break

    }
        }
    };
        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
        Setcontentview (R.layout.main);
        Open Strictmode mode Usevmstrictmode ();
    Init (); 
        } @Override protected void OnDestroy () {//Unregisterreceiver (this.receiver); We deliberately didn't release receiver here.
        Mhandler.removecallbacksandmessages (NULL);
            if (mthread! = null && mthread.isalive ()) {try {mthread.stop ();
 } catch (Exception e) {}}       Super.ondestroy (); }//Using threads may take time Runnable Runnable = new Runnable () {@Override public void run () {//check
            Cursorleak, Registered SQLite Cursor, did not call close String result = Cursorleakunclosetest ();
        Mhandler.sendmessage (Mhandler.obtainmessage (MSG_GET_DATA_OK, result));

    }
    };

        Initialize some keys such as private void Init () {mcontext = this;
        Mtextview = (TextView) This.findviewbyid (r.id.content);
        Mcursorleakbutton = (Button) This.findviewbyid (r.id.cursorleak);
        Mclosableleakbutton = (Button) This.findviewbyid (r.id.closableleak);
        Mactivityleakbutton = (Button) This.findviewbyid (r.id.activityleak);
        Mregistrationsleakbutton = (Button) This.findviewbyid (r.id.registrationobjectsleak);

        Mclassinstancelimitbutton = (Button) This.findviewbyid (r.id.setclassinstancelimit);
        Mcursorleakbutton.setonclicklistener (this);
        Mclosableleakbutton.setonclicklistener (this); MacTivityleakbutton.setonclicklistener (this);
        Mregistrationsleakbutton.setonclicklistener (this);
    Mclassinstancelimitbutton.setonclicklistener (this);
            } @Override public void OnClick (View v) {switch (V.getid ()) {r.id.cursorleak:
            LOG.I (TAG, "----------->onclick");
            Mtextview.settext ("Reading contact database, testing cursor leak, test results see: Data/system/dropbox Please wait ...");
            Mthread = new Thread (runnable);
            Mthread.start ();
        Break
            Case R.id.closableleak:mtextview.settext ("Test closableleak, test results see Data/system/dropbox");
            File Newxmlfile = new file (Environment.getexternalstoragedirectory (), "hello.txt");
                try {newxmlfile.createnewfile ();
                FileWriter FW = new FileWriter (newxmlfile);
                Fw.write ("Hellohellohello"); Fw.close ();
 We intentionally did not close the FW} catch (IOException e) {e.printstacktrace ();           } break; Case R.id.activityleak:mtextview.settext ("Test activity leaks, click Physical back to exit the app or rotate the screen (due to severe mode so it may crash unexpectedly), the test will need to kill the process to re-open
            , test results Please see: Data/system/dropbox ");     
                      New Thread () {@Override public void run () {while (true) {
                    Systemclock.sleep (1000);
            }}}.start ();
        Break Case R.id.registrationobjectsleak:mtextview.settext ("Test registrationobjects leak, check broadcastreceiver or ServiceCo Nnection whether the registered class object is properly disposed.
            Test results please see Data/system/dropbox ");  
            This.mreceiver = new Teststrictmodebroadcast ();  
            Intentfilter filter = new Intentfilter (); 
            Filter.addaction ("Android.intent.action.STRICT_MODE"); 
            Registerreceiver (this.mreceiver, filter);
        Break Case R.id.setclassinstancelimit:mtextview.settext ("Test setclassinstancelimit, set the same for a classThe upper limit of the instance in memory can assist in checking for memory leaks.
            Test results please see Data/system/dropbox ");
            for (int index=0; index<8; index++) {mclasslist.add (New classcounts ());
        } break; }}//Check cursorleak, register SQLite Cursor, do not call Close private String cursorleakunclosetest () {StringBuilder b
        Uilder = new StringBuilder ("");
        Contentresolver resolver = Getcontentresolver ();
        Insert 20 contacts for (int i = 1; i <; i++) {insertcontact ("contact" + I, "email" + I, "123" + i);
        }//Search contact CURSOR cursor = resolver.query (Contacts.Phones.CONTENT_URI, NULL, null,null, NULL); if (cursor! = NULL) {while (Cursor.movetonext ()) {String name = cursor.getstring (cursor.g
                Etcolumnindex (Contacts.Phones.NAME));
                Builder.append (name);
            Builder.append ("\ n"); }//cursor.close (); We're deliberately not closing the cursor here} return builder.tostring (); }//Open Strictmode mode private void Usevmstrictmode () {if (Debug_mode) {Strictmode.setvmpolicy (NE
            W StrictMode.VmPolicy.Builder (). Detectall (). Penaltydropbox (). Penaltydeath ()  
        . Penaltylog (). Setclassinstancelimit (Classcounts.class, 2). build ());
        }}//Insert Contact Protected Boolean insertcontact (String given_name, String work_email,string mobile_number) {
            try {contentvalues values = new Contentvalues ();
            Uri Rawcontacturi = Getcontentresolver (). Insert (Rawcontacts.content_uri, values);

            Long Rawcontactid = Contenturis.parseid (Rawcontacturi);
                Insert name data to the data table if (given_name! = "") {values.clear ();
                Values.put (data.raw_contact_id, Rawcontactid);
                Values.put (Data.mimetype, Structuredname.content_item_type); Values.put (Structuredname.given_name, Given_name);
            Getcontentresolver (). Insert (contactscontract.data.content_uri,values);
                } if (Mobile_number! = null) {values.clear ();
                Values.put (data.raw_contact_id, Rawcontactid);
                Values.put (Data.mimetype, Phone.content_item_type);
                Values.put (Phone.type, phone.type_mobile);
                Values.put (Phone.number, Mobile_number);
            Getcontentresolver (). Insert (contactscontract.data.content_uri,values);
                }//Insert the data table with the email if (Work_email! = "") {values.clear ();
                Values.put (data.raw_contact_id, Rawcontactid);
                Values.put (Data.mimetype, Email.content_item_type);
                Values.put (Email.data, Work_email);
                Values.put (Email.type, email.type_work);
            Getcontentresolver (). Insert (contactscontract.data.content_uri,values); }} catch (ExceptIon e) {e.printstacktrace ();
        return false;
    } return true; }

}

The above code requires the following permissions:

    Android:name= "Android.permission.READ_CONTACTS"/>
    <uses-permission android:name= " Android.permission.WRITE_CONTACTS "/>
    <uses-permission android:name=" Android.permission.WRITE_EXTERNAL _storage "/>
    <uses-permission android:name=" Android.permission.READ_EXTERNAL_STORAGE "/>

Above is the main code of the entire test demo, you can find, mainly open the strict mode, and then simulate the above background introduced in the five kinds of errors, such as the query database after the cursor forgot to close, registered after the broadcast did not cancel registration, etc., relatively speaking are more common but easy to miss the error. 7.Demo Run Analysis

With the demo above, we can run the program to perform the simulation test of the rigorous pattern discovery problem, and here we mainly write Dropbox and log print to briefly describe how to view the problem of severe mode detection.
The following is a description of the following five types of errors in the Dropbox log printing and resolution method. 7.1 Click the first button, check the Cursorleak error:

When you click on the Demo first button, because we did not close the cursor in the code simulation, the strict mode will print the following log in Dropbox:

System-app:false uptime-millis:14075239//...
The core focus of the rigorous mode is log ... Java.lang.Throwable:Explicit termination method ' close ' not called at Dalvik.system.CloseGuard.open (Closeguard.java: 184) at java.io.fileoutputstream.<init> (fileoutputstream.java:89) at java.io.fileoutputstream.<init> (fileoutputstream.java:72) at java.io.filewriter.<init> (filewriter.java:42) at com.meizu.strictmode.Strict Modeactivity.onclick (strictmodeactivity.java:133) at Android.view.View.performClick (view.java:4851) at ANDROID.V Iew. View$performclick.run (view.java:20016) at Android.os.Handler.handleCallback (handler.java:739) at Android.os.Hand Ler.dispatchmessage (handler.java:95) at Android.os.Looper.loop (looper.java:135) at android.app.ActivityThread.ma In (activitythread.java:5424) at Java.lang.reflect.Method.invoke (Native Method) at Java.lang.reflect.Method.invok E (method.java:372) at Com.android.internal.os.zygoteinit$methodAndargscaller.run (zygoteinit.java:947) at Com.android.internal.os.ZygoteInit.main (zygoteinit.java:742) 

Through the above log can easily find the point of the problem, not only give a potential error description, and give the approximate location of the problem, so it is easy to locate the problem, and not waste a lot of time to search blindly, or did not find themselves forget to adjust the Close method. The
log can be used to find that the solution to this type of problem is to appear in pairs, close the cursor;
Click the second button, check closableleak 7.2 When you click on the demo second button, we simulate the file read and write, but there is no way to transport the Colse method, you will get the following main log (get the same method as above):

    Java.lang.Throwable:Explicit termination method ' close ' not called at Dalvik.system.CloseGuard.open (Closeguard.ja va:184) at java.io.fileoutputstream.<init> (fileoutputstream.java:89) at java.io.fileoutputstream.<init& gt; (fileoutputstream.java:72) at java.io.filewriter.<init> (filewriter.java:42) at COM.MEIZU.STRICTMODE.STR Ictmodeactivity.onclick (strictmodeactivity.java:133) at Android.view.View.performClick (view.java:4851) at Androi D.view.view$performclick.run (view.java:20016) at Android.os.Handler.handleCallback (handler.java:739) at Android. Os. Handler.dispatchmessage (handler.java:95) at Android.os.Looper.loop (looper.java:135) at Android.app.ActivityThrea D.main (activitythread.java:5424) at Java.lang.reflect.Method.invoke (Native Method) at java.lang.reflect.method.i Nvoke (method.java:372) at Com.android.internal.os.zygoteinit$methodandargscaller.run (ZygoteInit.java:947) at COM . Android.internal.os.Zygoteinit.main (zygoteinit.java:742) 

As you can see, the error log, similar to the first button, is given above, and we can fix the potential problem by locating the log analysis quickly. 7.3 Click the third button, check activityleak:

Similar to the above two, we give the error log directly, as follows:

Instance-count:2android.os.strictmode$instancecountviolation:class com.meizu.strictmode.StrictModeActivity; instances=2; Limit=1 at
android.os.StrictMode.setClassInstanceLimit (strictmode.java:1)

It can be seen that this type of potential error after the emergence of the strict mode can be given the relevant information, but not the above several obvious, but at least can tell us which activity has a memory leak, which has helped us narrow the problem range, Next, we can use other memory leak detection tools for detailed location analysis. 7.4 Click the fourth button, check registrationobjectsleak:

Similar to the above, give the error log directly, as follows:

Android.app.IntentReceiverLeaked:Activity Com.meizu.strictmode.StrictModeActivity has leaked intentreceiver Com.meizu.strictmode.teststrictmodebroadcast@345916f7 that is originally registered here. Is missing a call to Unregisterreceiver ()?

The analysis method is similar to the above and is not burdensome. 7.5 Click the fifth button, check setclassinstancelimit:

Ibid., error log is as follows:

Android.os.strictmode$instancecountviolation:class com.meizu.strictmode.strictmodeactivity$classcounts; instances=16; limit=2 at
android.os.StrictMode.setClassInstanceLimit (strictmode.java:1)   

You can see that the reason for the error is to turn on the strict mode, we set a class to create a maximum number of objects, but we do not follow, so the solution is to set a class to create the maximum number of objects do not exceed the upper limit. 8. Summary of the rigorous model

With the above background knowledge and demo and demo of the problem log analysis we can summarize as follows:
The meaning of the rigorous mode:
We usually write code may be due to a moment of negligence and other causes of the code potential problems, but our code can be normal execution, intuitive feel no problem, so no longer respond to, but we can not guarantee that the end user and we do not have the same problem (for example, we directly in the UI thread to look at a theory that the fast things, Our test environment may not be able to cover the limits of this query-it has not been found, and the end user occasionally reaches this limit, which is the underlying cause of our neglect to cause functional ANR. , so we have to find a way to get the code as performance and stability as possible, and the harsh mode is to let some potential problems leak in the development phase of the tool.
Use of harsh mode:
The above background and demo are introduced, basically is in the development phase of the code to carry out the strict mode configuration, and then look at the Logcat print and Dropbox files, found a destroy one can

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.