Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to avoid creating unnecessary objects in Android

2025-04-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces you how to avoid creating unnecessary objects in Android, the content is very detailed, interested friends can refer to, I hope it can be helpful to you.

In programming development, the occupation of memory is a reality that we often have to face, and the usual direction of memory tuning is to minimize the footprint of memory. Avoiding the creation of unnecessary objects is an important aspect.

Android devices do not have as much memory as PC, and the memory consumed by a single App is actually relatively small. So avoiding creating unnecessary objects is particularly important for Android development.

The editor will introduce some common scenarios and methods to avoid creating objects, some of which are micro-optimization, some are coding techniques, and of course there are methods that can make a difference.

Use singleton

Singleton is our common design pattern, with which we can provide only one object for global invocation. So singletons are a way to avoid creating unnecessary objects.

The singleton mode is easy to use, but it needs to pay attention to many problems, the most important thing is to ensure the uniqueness of the singleton in the case of multi-thread concurrency. Of course, there are many ways, such as hungry Han style, lazy double-check and so on. Here is a geek way of writing singles.

Public static 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. Using this principle, we can make use of this feature, combined with the inner class, we can implement the above code to create an instance like a slacker.

Avoid implicit packing

Autoboxing is a feature introduced by Java 5 that automatically converts data of the original type to the corresponding reference type, such as converting int to Integer.

This feature greatly reduces the trivial work of coding, but a little carelessness may create unnecessary objects. For example, the following code

Integer sum = 0; for (int I = 1000; I

< 5000; i++) { sum += i; } 上面的代码sum+=i可以看成sum = sum + i,但是+这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,***发生自动装箱操作转换成Integer对象。其内部变化如下 int result = sum.intValue() + i; Integer sum = new Integer(result); 由于我们这里声明的sum为Integer类型,在上面的循环中会创建将近4000个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。 另外,当将原始数据类型的值加入集合中时,也会发生自动装箱,所以这个过程中也是有对象创建的。如有需要避免这种情况,可以选择SparseArray,SparseBooleanArray,SparseLongArray等容器。 谨慎选用容器 Java和Android提供了很多编辑的容器集合来组织对象。比如ArrayList,ContentValues,HashMap等。 然而,这样容器虽然使用起来方便,但也存在一些问题,就是他们会自动扩容,这其中不是创建新的对象,而是创建一个更大的容器对象。这就意味这将占用更大的内存空间。 以HashMap为例,当我们put key和value时,会检测是否需要扩容,如需要则双倍扩容 @Override public V put(K key, V value) { if (key == null) { return putValueForNullKey(value); } //some code here // No entry for (non-null) key is present; create one modCount++; if (size++ >

Threshold) {tab = doubleCapacity (); index = hash & (tab.length-1);} addNewEntry (key, value, hash, index); return null;}

On the issue of capacity expansion, there are usually the following methods

Estimate a larger capacity value to avoid multiple capacity expansion

Find alternative data structures to ensure a balance between time and space

Make good use of LaunchMode

It is mentioned that LaunchMode must have something to do with Activity. Normally we declare Activity in manifest and use the default standard mode if we don't set LaunchMode.

Once set to standard, every time there is an Intent request, a new Activity instance is created. For example, if there are 10 Intent composing emails, then 10 instances of ComposeMailActivity will be created to handle those Intent. As a result, it is clear that this pattern creates multiple instances of an Activity.

If you actually keep an Activity example for a search-enabled Activity, using the standard pattern will cause too many Activity instances to be created, which is not good.

Ensure that in accordance with the common sense, the reasonable use of LaunchMode, reduce the creation of Activity.

Activity handles onConfigurationChanged

This is also related to the creation of Activity objects, because Activity creation is much more expensive than other objects.

By default, when we rotate the screen, the original Activity is destroyed and a new Activity is created to handle layout adaptation. Of course, this is the default practice of the system, and we can avoid recreating the Activity when we develop it under control.

Take screen switching as an example, when you declare Activity, add

Then override the onConfigurationChanged method of Activity

@ Override public void onConfigurationChanged (Configuration newConfig) {super.onConfigurationChanged (newConfig); if (newConfig.orientation = = Configuration.ORIENTATION_PORTRAIT) {setContentView (R.layout.portrait_layout);} else if (newConfig.orientation = = Configuration.ORIENTATION_LANDSCAPE) {setContentView (R.layout.landscape_layout);}}

Pay attention to string concatenation

The string is perhaps the least conspicuous. This is mainly about the concatenation of strings.

Log.i (LOGTAG, "onCreate bundle=" + savedInstanceState)

This is probably the most common way to type log, but the inner part of string concatenation is actually the process of generating StringBuilder objects and then append them one by one until the toString method is called.

The following is a code loop, which is obviously bad because a lot of StringBuilder objects are created.

Public void implicitUseStringBuilder (String [] values) {String result = "; for (int I = 0; I < values.length; iTunes +) {result + = values [I];} System.out.println (result);}

The ways to reduce string concatenation are

Replace with String.format

If it is a loop stitching, it is recommended to explicitly create a StringBuilder outside the loop to use the

Reduce layout hierarchy

Too many layout levels not only make the inflate process time-consuming, but also create extra auxiliary layouts. Therefore, it is necessary to reduce the auxiliary layout. You can try other layouts or custom views to solve this kind of problem.

Check in advance to reduce unnecessary anomalies

Exceptions are normal for a program, but the code for exceptions is actually very high because it needs to collect on-site data stacktrace. However, there are some measures to avoid exception throwing, and that is to do some pre-checking.

For example, if we want to print each line of string in a file, the unchecked code is as follows, and it is possible for FileNotFoundException to throw.

Private void printFileByLine (String filePath) {try {FileInputStream inputStream = new FileInputStream ("textfile.txt"); BufferedReader br = new BufferedReader (new InputStreamReader (inputStream)); String strLine; / / Read File Line ByLine 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 check the existence of the file, the probability of throwing a FileNotFoundException will be greatly reduced.

Private void printFileByLine (String filePath) {if (! new File (filePath). Exists ()) {return;} try {FileInputStream inputStream = new FileInputStream ("anonymous.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 and is recommended.

Don't create too many threads

In android, we should try to avoid performing time-consuming operations in the main thread, so we need to use other threads.

Private void testThread () {new Thread () {@ Override public void run () {super.run (); / / do some io work}} .start ();}

Although these work, the cost of creating a thread is much higher than a normal object, and it is recommended to use HandlerThread or ThreadPool as a replacement.

Use annotations instead of enumerations

Enumerations are often used as a means of value qualification, and the use of enumerations is more reliable than a simple constant convention. Then the essence of enumeration is to create objects. Fortunately, Android provides annotations that limit values to compile time, thereby reducing runtime pressure. The related annotations are IntDef and StringDef.

Here's how to use IntDef as an example

Declare the following in a file

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 method like writing

Private void setDoorState (@ AppConstants.DoorState int state) {/ / some code}

Only STATE_OPEN,STATE_CLOSE and STATE_BROKEN can be used when calling a method. Using other values results in compilation reminders and warnings.

Select object pool

There are many concepts of pool in Android, such as thread pool, connection pool. Including our long-used Handler.Message is the use of pooling technology.

For example, if we want to use Handler to send messages, we can use Message msg = new Message () or Message msg = handler.obtainMessage (). Using pooling does not create new objects every time, but gives priority to fetching objects from the pool.

There are several points to pay attention to when using object pooling

Put the object back into the pool and pay attention to initializing the data of the object to prevent the existence of dirty data

Reasonably control the growth of the pool to avoid being too large, resulting in many objects being idle.

Initialize Application carefully

Android applications can support starting multiple processes. The usual practice is like this

Usually we do a lot of initialization operations in the onCreate method of Application, but every process startup needs to execute this onCreate method. In order to avoid unnecessary initialization, it is recommended to initialize according to the process (by judging the current process name).

Public class MyApplication extends Application {private static final String LOGTAG = "MyApplication"; @ Override public void onCreate () {String currentProcessName= getCurrentProcessName (); Log.i (LOGTAG, "onCreate currentProcessName=" + currentProcessName); super.onCreate () If (getPackageName (). Equals (currentProcessName)) {/ / init for default process} else if (currentProcessName.endsWith (": network")) {/ / init for netowrk process}} private String 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 }} on how to avoid creating unnecessary objects in Android to share here, I hope the above content can be of some help to you, you can learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report