"Reprint" How to avoid creating unnecessary objects in Android

Source: Internet
Author: User

In programming development, the memory footprint is the reality that we often face, the direction of the usual memory tuning is to minimize the memory footprint. This avoids the creation of unnecessary objects as an important aspect.

Android devices don't have enough memory like a PC, and a single app consumes less memory. So avoiding the creation of unnecessary objects is especially important for Android development.

This article introduces some common scenarios and methods to avoid creating objects, some of which are micro-optimizations, some of which are coding techniques, and of course there are ways that can really make a difference.

Use a single case

Singleton is our common design pattern, and with this pattern, we can provide only one object for global invocation. Therefore, a singleton is a way to avoid creating unnecessary objects.

The singleton mode is easy to get started, but there are a lot of problems to be aware of, and the most important thing is to guarantee the uniqueness of single cases with multithreading concurrency. Of course, many ways, such as a hungry man-style, lazy double-check and so on. Here is a description of a very geek's way of writing a single case.

public class singleinstance {private singleinstance () {}  public static singleinstance  Getinstance () {return singleinstanceholder.sinstance;} private static  class singleinstanceholder { Private static singleinstance sinstance = new SingleInstance () ; }} 

In Java, the static initialization of the class will be triggered when the class is loaded, we use this principle, we can realize the use of this feature, combined with the inner class, you can implement the above code, the lazy create an instance.

Avoid implicit boxing

Automatic boxing is a feature introduced by Java 5 that automatically converts data from the original type to the corresponding reference type, such as converting int to integer.

This feature greatly reduces the trivial work of coding, but it is possible to create unnecessary objects with little attention. For example, the following code

0; For (int i=, i<,i++) {   sum+=i;}   

The above code sum+=i can be considered sum = sum + I, but the + operator does not apply to an integer object, the sum is automatically unboxing, the value is added, and the last automatic boxing operation is converted to an integer object. The internal changes are as follows

New Integer (result);

Since the sum we declare here is of type integer, nearly 4,000 useless integer objects are created in the above loop, which in this large loop degrades the performance of the program and increases the amount of garbage collected. So when we're programming, we need to be aware of this and correctly declare variable types to avoid performance problems caused by automatic boxing.

Also, automatic boxing occurs when the value of the original data type is added to the collection, so there are objects created in the process. If there is a need to avoid this situation, you can choose, and wait for the SparseArray SparseBooleanArray SparseLongArray container.

Careful selection of containers

Java and Android provide a large collection of edited containers to organize objects. For example ArrayList , and ContentValues HashMap so on.

However, this container is easy to use, but there are some problems, that is, they will automatically expand, which is not to create a new object, but rather to create a larger container object. This means that it takes up more memory space.

Take HashMap as an example, when we put the key and value, we will detect if we need to expand, and if necessary, double the expansion

@put (value) {        return putvaluefornullkey (null;}   

There are several ways of scaling up

    • Estimate a larger capacity value to avoid multiple expansions
    • Find alternative data structures to ensure a balance of time and space
Use the Launchmode.

The mention of Launchmode is bound to be related to activity. Normally we declare activity in manifest and use the default standard mode if you do not set Launchmode.

Once set to standard, a new activity instance is created whenever a intent request is made. For example, if you have 10 intent that compose a message, you will create 10 instances of composemailactivity to handle these intent. As a result, it is clear that this pattern creates multiple instances of an activity.

If you are actually keeping an activity example for the activity of a search function, using standard mode causes too many instances of the activity to be created, and therefore not good.

Ensure reasonable use of launchmode and reduce activity creation.

Activity handling Onconfigurationchanged

This is another related to activity object creation, because activity creates a much higher cost relative to other objects.

By default, when we rotate the screen, the original activity is destroyed, a new activity is created, and the reason for this is to handle the layout adaptation. This is, of course, the system default, and we can avoid recreating the activity when we are developing a controllable situation.

As an example of screen switching, when the activity is declared, add

<activity    android:name=". Mainactivity "    android:label=" @string/app_name "    android:theme=" @style/apptheme.noactionbar "    android:configchanges="orientation" >   

Then rewrite the activity's Onconfigurationchanged method

Onconfigurationchanged(Configuration newconfig) {    if (newconfig.orientation = = Configuration.orientation_landscape) {Setcontentview (r.layout.landscape_layout);}} 
Note string concatenation

The string is perhaps the most humble of all. The main talk here is the concatenation of strings

LOG.I ("onCreate bundle=" + savedinstancestate);

This should be our most common way of playing log, however, the concatenation of strings is actually generated StringBuilder objects, and then each append, until the last call to the ToString method process.

Here is the code loop code, which is obviously bad, because it creates a lot of StringBuilder objects.

void  Implicitusestringbuilder (string[] values) {for  (0; i < values.length; i + +) {result + = Values[i]; } System. out.println (result);}    

There are ways to reduce string concatenation

    • Replace with String.Format
    • In the case of circular stitching, it is recommended to explicitly create StringBuilder outside of the loop using
Reduce layout levels

Too many layout hierarchies not only lead to a time-consuming process, but also create redundant secondary layouts for inflate. Therefore, it is necessary to reduce the auxiliary layout. You can try other layout methods or customize the view to solve this kind of problem.

Check in advance to reduce unnecessary anomalies

Exception for the program, in the usual, and then in fact the exception code is very high, because it needs to collect the field data StackTrace. However, there are some measures to avoid exception throws, that is to do some early check.

For example, we want to print a file of each line of string, did not do check the code below, is the existence of filenotfoundexception thrown possible.

Privatevoid printfilebyline (String FilePath) {try {fileinputstream InputStream = new FileInputStr EAM ( "textfile.txt"); BufferedReader br = new BufferedReader (new InputStreamReader ( InputStream)); String StrLine; //read File line by line while ((StrLine = Br.readline ())! = null) {//Print the content on the console System.out.println (StrLine); } br.close (); } catch (FileNotFoundException e) {e.printstacktrace ();} catch (IOException e) {e.printstacktrace ();}}       

If we do check for the existence of the file, the probability of throwing the filenotfoundexception will be reduced a lot,

PrivatevoidPrintfilebyline (String FilePath) {if (! New File (FilePath). Exists ()) {return;} try {fileinputstream InputStream = new FileInputStream ( "textfile.txt"); BufferedReader br = new BufferedReader (new InputStreamReader ( InputStream)); String StrLine; //read File line by line while ((StrLine = Br.readline ())! = null) {//Print the content on the console System.out.println (StrLine); } br.close (); } catch (FileNotFoundException e) {e.printstacktrace ();} catch (IOException e) {e.printstacktrace ();}}       

The above check is a good coding technique that is recommended for adoption.

Do not create threads too much

In Android, we should try to avoid time-consuming operations in the main thread and therefore need to use other threads.

Testthread() {    run//do some io work}}.start ();}  

While these work, creating threads is much more expensive than regular objects, and it is recommended to replace them with Handlerthread or ThreadPool.

Using annotations instead of enumerations

Enumerations are often used as a means of value qualification, and using enumerations is more reliable than simple constants conventions. The essence of the enumeration is then to create the object. Fortunately, Android provides annotations that allow values to be defined at compile time, thus reducing the pressure on the runtime. The relevant annotations are intdef and stringdef.

The following is an example of Intdef, which describes how to use

In a file, declare as follows

public class appconstants {public static final int state_open = 0; public static final int state_close = 1; public static final int State_broken = 2;  @IntDef ({state_open, state_close, State_broken}) public  @interface doorstate {}}           

And then set up a way to write like this

Setdoorstate//some Code}

Can only be used when calling methods STATE_OPEN , STATE_CLOSE and STATE_BROKEN . Using other values can cause compilation reminders and warnings.

Select Object Pool

There are many pools of concepts in Android, such as the thread pool, connection pooling. Handler.message, including our long-time use, is the technology that uses the pool.

For example, we want to send a message using handler, which can be used Message msg = new Message() or used Message msg = handler.obtainMessage() . Using a pool does not create new objects every time, but rather takes objects from the pool.

There are several points to be aware of using object pooling

    • Put the object back in the pool, taking care to initialize the object's data to prevent the presence of dirty data
    • Reasonable control of the growth of the pool, avoid too large, causing many objects in idle state
Careful initialization of application

Android apps can support opening multiple processes. The usual practice is this

<android:name=". NetworkService "    android:process=": Network "/>   

Usually we onCreate do a lot of initialization in the application method, but each process start needs to execute to this oncreate method, in order to avoid unnecessary initialization, it is recommended to follow the process (by judging the current process name) corresponding initialization.

PublicClassMyApplicationExtendsApplication {PrivateStaticFinal String LogTag ="MyApplication";@OverridePublicvoidOnCreate() {String currentprocessname = Getcurrentprocessname (); LOG.I (LogTag,"OnCreate currentprocessname=" + currentprocessname);Super.oncreate ();if (Getpackagename (). Equals (Currentprocessname)) {Init for Default Process}Elseif (Currentprocessname.endswith (//init for Netowrk Process}} private String Span class= "Hljs-title" >getcurrentprocessname () {String currentprocessname = " "; int pid = Android.os.Process.myPid (); Activitymanager manager = (activitymanager) this.getsystemservice (Context.ACTIVITY_ SERVICE); for (Activitymanager.runningappprocessinfo processInfo:manager.getRunningAppProcesses ()) {if (processinfo.pid = = pid) {currentprocessname = Processinfo.processname; break; }} return currentprocessname;}         

Some of the above knowledge is a summary of how to avoid creating unwanted objects in Android. Welcome comments and views, and make progress together.

"Reprint" How to avoid creating unnecessary objects in Android

Related Article

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.