Android APP优化—Android程序员必须掌握

一、Android 内存优化—避免OOM

1. 减小对象内存的占用

(1)使用更轻量级的数据结构,SparseArray/ArrayMap代替HashMap
(2)避免使用枚举Enum,因为枚举占用内存空间要比整型大。
(3)减小Bitmap内存占用。如可设置inSampleSize,Decode format{ARGB_8888/RGB_565/ARGB_4444/ALPHA}
(4)字符串拼接使用StringBuilder等
(5)避免在onDraw方法里面执行对象的创建
(7)谨慎使用static对象
(8)常量需要使用static final 来修饰。

2. 内存对象的复用

(1)ListVierw优化

a. 使用ViewHolder,避免在Adapter的getView方法中做耗时操作。
b.在列表滑动状态时,不执行异步加载任务。
c.可以开启硬件加速是滑动更流畅。

(2)Bitmap对象的复用,不用时调用bitmap.recycler()方法进行回收。
(3)使用Cursor,文件IO操作时,及时关闭。

3. 避免内存泄漏

(1)尽量使用静态内部类,可以避免持有外部引用而发生内存泄漏。
如Actvity中Handler容易内存溢出,有三种方式解决:
(a)自定义handler处理为静态内部类 + activity的weakReference方式。
(b)在activity中的ondestroy方法中调用handler.removeCallbacksAndMessages(null)方法。
(c)把成员变量handler使用static来修饰。
————————-
(2)Context尽量使用getApplicationContext

二、Android 线程优化

1. 为何需要线程优化???

因为在操作系统中,线程是操作系统的调度的最小单元,同时线程又是一种受限的系统资源,即线程不可能无限制地产生,并且线程的创建和销毁都会相应的开销。线程池可以有效的控制线程池的最大并发数,避免大量线程因相互抢夺资源而发生阻塞。

2. 如何优化?

采用线程池,在这个线程池中会缓存一定数量的线程,通过线程池就可以避免因为频繁创建和销毁线程所带来的系统开销。而不是每次都要去创建一个Thread对象。

简单示例代码如下:

/**
 * Created by ronindong on 2017/7/13.
 */

public final class XThread {
    /**
     * 默认线程池大小
     */
    private static final int nThreads = 10;
    /**
     * 线程池
     */
    private final static ExecutorService mService;

    static {
        mService = Executors.newFixedThreadPool(nThreads);
    }

    /**
     * 线程池执行线程
     * @param r
     */
    public static void execute(Runnable r) {
        if (mService != null) {
            mService.execute(r);
        }
    }

    /**
     * 执行线程并获取返回值
     * @param callable
     * @param <T>
     * @return
     */
    public static <T> T submit(Callable<T> callable) {
        FutureTask<T> task = new FutureTask<>(callable);
        if (mService != null) {
            mService.submit(task);
        }
        try {
            return task.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {

        Integer num = XThread.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                //do something
                return 100;
            }
        });

        assert num != null;
        System.out.println(num.intValue());
    }

三、Android 避免ANR产生

原因:
ANR的产生原因主要因为在UI主线程中做了耗时操作。在Android中,Activity在5秒内无法响应触摸事件或键盘输入就会发生ANR;在BroadcastReceiver中如果10s内还未完成操作也会出现ANR。
解决方法:
把耗时任务放到工作线程中执行,即采用异步方式处理耗时操作。或者使用AsyncTask(也是使用线程池实现的)


参见之前文章:Android XHandler —极大方便UI线程和工作线程的切换

四、Android 布局优化

1. 尽量减少布局文件的层级 — 布局层级的减少,android绘制的工作也就减少,性能就会越好。

(1)使用<include/>标签 - 功能重用布局
(2)使用<merge/>标签 - 一般配合<include/>标签使用,可以减少布局层级
(3)使用ViewStub控件 - 按需加载布局,实现延迟加载,提高应用的响应速度。

五、Android View绘制优化

1. 绘制优化是指View的onDraw方法中不要执行耗时操作。

(1)不要在onDraw方法中,创建局部变量。——因为onDraw方法可能会被频繁的调用,这样就会产生大量的局部变量,占用了更多的内存。内存占用过高,可能会出发GC垃圾回收,降低程序执行效率。
(2)不要在onDraw方法中执行耗时任务。——执行耗时任务会是view的绘制不流畅,影响应用性能。

六、Android 检测内存泄漏

1. MAT工具:(Eclipse Memory Analyzer)是一款强大的内存泄漏分析工具。
下载地址:MAT工具
2. 开源库LeakCanary:集成到项目中,若是发生内存泄漏,会提示你具体哪个对象产生的内存泄漏,很方便。如下样例图:

LeakCanary内存泄漏图

Github地址:LeakCanary

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的程序员计算器的代码示例,仅供参考: MainActivity.java 文件: ``` import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends AppCompatActivity { EditText inputEditText; TextView resultTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); inputEditText = findViewById(R.id.inputEditText); resultTextView = findViewById(R.id.resultTextView); Button decimalButton = findViewById(R.id.decimalButton); decimalButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { calculate(10); } }); Button binaryButton = findViewById(R.id.binaryButton); binaryButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { calculate(2); } }); Button octalButton = findViewById(R.id.octalButton); octalButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { calculate(8); } }); Button hexadecimalButton = findViewById(R.id.hexadecimalButton); hexadecimalButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { calculate(16); } }); } private void calculate(int radix) { String input = inputEditText.getText().toString(); try { long num = Long.parseLong(input, radix); String result = Long.toString(num, radix); resultTextView.setText(result); } catch (NumberFormatException e) { resultTextView.setText("Invalid input"); } } } ``` activity_main.xml 文件: ``` <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" tools:context=".MainActivity"> <EditText android:id="@+id/inputEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Input number here" android:inputType="number" /> <Button android:id="@+id/decimalButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/inputEditText" android:layout_marginTop="16dp" android:text="Decimal" /> <Button android:id="@+id/binaryButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/inputEditText" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_toEndOf="@+id/decimalButton" android:text="Binary" /> <Button android:id="@+id/octalButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/inputEditText" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_toEndOf="@+id/binaryButton" android:text="Octal" /> <Button android:id="@+id/hexadecimalButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/inputEditText" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_toEndOf="@+id/octalButton" android:text="Hexadecimal" /> <TextView android:id="@+id/resultTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/decimalButton" android:layout_marginTop="16dp" android:text="" /> </RelativeLayout> ``` 这个示例代码实现了一个简单的程序员计算器,可以将用户输入的数字转换为十进制、二进制、八进制或十六进制,并显示计算结果。需要注意的是,这只是一个简单的示例代码,实际开发中可能需要进行更多的功能扩展和优化

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ronindong

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值