【Android 性能优化】应用启动优化 ( 方法追踪代码模板 | 示例项目 | SD 卡访问权限 | 示例代码 | 获取 Trace 文件 | Android Studio 查看文件)

简介: 【Android 性能优化】应用启动优化 ( 方法追踪代码模板 | 示例项目 | SD 卡访问权限 | 示例代码 | 获取 Trace 文件 | Android Studio 查看文件)

文章目录

一、 方法追踪代码模板

二、 追踪 Launch 页面的 onCreate 方法执行情况

1. 示例项目

2. SD 卡访问权限问题 ( 动态权限申请 )

3. MainActivity onCreate 方法追踪及动态权限申请

三、 查看 SD 卡根目录的 trace 文件

四、 Android Studio 中分析该 Trace 文件





一、 方法追踪代码模板


调用 Debug.startMethodTracing(traceFile.getAbsolutePath()) 开始追踪分析方法执行情况 , 传入文件路径作为参数 , 当执行 Debug.stopMethodTracing() 方法时 , 会将方法追踪信息保存到 traceFile.getAbsolutePath() 代表的文件路径中 ;


在下面的代码中 , 方法追踪信息被保存到了 SD 卡下的 Method_Trace 文件中 ;




1. 方法追踪使用流程 :



① 创建 File 对象 : 方法的执行信息 , 将被保存到该 File 文件中 ;


File traceFile = new File(Environment.getExternalStorageDirectory(), "Method_Trace");


② 开始方法追踪 : 在该方法中 , 需要传入上述 File 文件的绝对路径 , 才能向该 File 文件中保存方法执行信息 ;


Debug.startMethodTracing(traceFile.getAbsolutePath());


③ 停止方法追踪 : 调用该方法后 , 结束追踪 , 可以将 File 文件导出 , 并在 Android Studio 工具中分析方法执行情况 ;


Debug.stopMethodTracing();



2. 代码示例 :


// 1. 将追踪信息存放到该文件中
File traceFile = new File(Environment.getExternalStorageDirectory(), "Method_Trace");
// 2. 开启方法追踪
Debug.startMethodTracing(traceFile.getAbsolutePath());
// TODO 要追踪的内容
// 3. 停止方法追踪
Debug.stopMethodTracing();





二、 追踪 Launch 页面的 onCreate 方法执行情况




1. 示例项目


1 . 示例项目 : 以上一个项目直播推流的 MainActivity 为例 , 在该 Launch Activity 的 onCreate 方法中 , 添加上述方法追踪信息 , 追踪方法执行情况 , 项目地址 han1202012 / RTMP_Pusher ;




2. SD 卡访问权限问题 ( 动态权限申请 )


1. 权限问题 : 我用的是 Google Pixel 2 手机作为测试机 , 使用的是 Android 10 系统 , 此时出现动态权限问题 ;



2. SD 卡访问权限 : Debug.startMethodTracing(traceFile.getAbsolutePath()) 方法作用是将方法追踪信息写出到 SD 卡的文件中 , 因此这里必须 动态申请 SD 卡的访问权限 ;



3. 静态声明权限 : 在 AndroidManifest.xml 文件中添加 SD 卡的访问权限 : 最后两个是 SD 卡访问权限 ;


<!-- 前 4 个权限是读写权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!-- 最后两个权限是 SD 卡访问权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


4. 动态权限申请 : MainActivity 中使用相关权限之前 , 必须先动态申请权限 , 否则无法进行方法追踪 ;



注意 : 动态权限申请 , 必须要在 Debug.startMethodTracing 方法之前调用 , 否则开始方法追踪在没有 SD 卡访问权限的情况下执行 , 直接崩溃 ;




3. MainActivity onCreate 方法追踪及动态权限申请


下面代码中有 ★ 的代码是方法追踪相关代码 ; 添加了 3 33 行方法追踪相关代码 ;


动态权限申请代码 : 其中 [   31 , 71   ] [ \, 31 , 71 \,][31,71] 行区间内的代码是动态权限申请相关代码 ;


方法追踪代码 : 第 88 , 90 , 124 88 , 90 , 12488,90,124 行代码是方法追踪相关代码 ;



package kim.hsl.rtmp;
import android.Manifest;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Environment;
import android.view.SurfaceView;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
public class MainActivity extends AppCompatActivity {
    /**
     * 显示图像的 SurfaceView 组件
     */
    private SurfaceView mSurfaceView;
    /**
     * 直播推流器
     */
    private LivePusher mLivePusher;
    /**
     * 需要获取的权限列表
     */
    private String[] permissions = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.INTERNET,
            Manifest.permission.MODIFY_AUDIO_SETTINGS,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.CAMERA
    };
    /**
     * 动态申请权限的请求码
     */
    private static final int PERMISSION_REQUEST_CODE = 888;
    /**
     * 动态申请权限
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    private void initPermissions() {
        if (isLacksPermission()) {
            //动态申请权限 , 第二参数是请求吗
            requestPermissions(permissions, PERMISSION_REQUEST_CODE);
        }
    }
    /**
     * 判断是否有 permissions 中的权限
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public boolean isLacksPermission() {
        for (String permission : permissions) {
            if(checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED){
                return true;
            }
        }
        return false;
    }
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        /*
            此时应用首界面启动完成, 将主题恢复成其它主题
            此处也可以根据不同的设置, 为应用设置不同的主题
         */
        setTheme(R.style.AppTheme);
        super.onCreate(savedInstanceState);
        // 初始化权限
        initPermissions();
        // ★ 1. 将追踪信息存放到该文件中
        File traceFile = new File(Environment.getExternalStorageDirectory(), "Method_Trace");
        // ★ 2. 开启方法追踪
        Debug.startMethodTracing(traceFile.getAbsolutePath());
        setContentView(R.layout.activity_main);
        mSurfaceView = findViewById(R.id.surfaceView);
        // 创建直播推流器, 用于将采集的视频数据推流到服务器端
        // 800_000 代表 800K 的码率
        mLivePusher = new LivePusher(this,
                640, 480, 800_000, 10,
                Camera.CameraInfo.CAMERA_FACING_BACK);
        // 设置 Camera 采集的图像本地预览的组件, 在 mSurfaceView 界面先绘制摄像头
        // 此处要为 SurfaceHolder 设置 SurfaceHolder.Callback 回调 , 通过里面的回调函数
        // 驱动整个推流开始
        mLivePusher.setPreviewDisplay(mSurfaceView.getHolder());
        findViewById(R.id.button_play).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // rtmp://123.56.88.254/myapp/0
                // 0 相当于 直播的 密码
                // 配置好服务器后, 记录 IP 地址, 替换 123.56.88.254 IP 地址
                // rtmp://123.56.88.254/myapp/mystream 地址推流后
                // 可以直接在 RTMP 服务器端的主页, 使用 JWPlayer 观看直播内容
                // 网页地址是 http//123.56.88.254:8080/
                String rtmpServerAddress = "rtmp://123.56.88.254/myapp/mystream";
                mLivePusher.startLive(rtmpServerAddress);
                ((TextView)findViewById(R.id.textViewUrl))
                        .setText("推流地址 : " + rtmpServerAddress);
            }
        });
        // ★ 3. 停止方法追踪
        Debug.stopMethodTracing();
    }
}






三、 查看 SD 卡根目录的 trace 文件


应用启动完毕后 , onCreate 方法执行完毕 , 该方法追踪文件就会在 SD 卡根目录生成 ;


回顾下存放方法追踪信息的文件创建过程 , 将 Trace 信息存储到了 SD 卡根目录的 Method_Trace 文件中 ;


// ★ 1. 将追踪信息存放到该文件中
File traceFile = new File(Environment.getExternalStorageDirectory(), "Method_Trace");


image.png





四、 Android Studio 中分析该 Trace 文件


直接将该文件拖入 Android Studio 中即可 ;


image.png

目录
相关文章
|
25天前
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
Android远程连接和登录FTPS服务代码(commons.net库)
22 1
|
1月前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异:从代码到用户体验
【10月更文挑战第5天】在移动应用开发的广阔天地中,安卓和iOS两大平台各占半壁江山。它们在技术架构、开发环境及用户体验上有着根本的不同。本文通过比较这两种平台的开发过程,揭示背后的设计理念和技术选择如何影响最终产品。我们将深入探讨各自平台的代码示例,理解开发者面临的挑战,以及这些差异如何塑造用户的日常体验。
|
2月前
|
存储 Java Android开发
🔥Android开发大神揭秘:从菜鸟到高手,你的代码为何总是慢人一步?💻
在Android开发中,每位开发者都渴望应用响应迅速、体验流畅。然而,代码执行缓慢却是常见问题。本文将跟随一位大神的脚步,剖析三大典型案例:主线程阻塞导致卡顿、内存泄漏引发性能下降及不合理布局引起的渲染问题,并提供优化方案。通过学习这些技巧,你将能够显著提升应用性能,从新手蜕变为高手。
28 2
|
Java Android开发
Android NDK开发系列教程3:基本方法调用及传参(续)
终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~ 上一节主要讲解Java向native传参,下面主要讲解从native传相应的数据到java层。
1257 0
|
3天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
5天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
7天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
【10月更文挑战第35天】在数字化时代,安卓应用的开发成为了一个热门话题。本文旨在通过浅显易懂的语言,带领初学者了解安卓开发的基础知识,同时为有一定经验的开发者提供进阶技巧。我们将一起探讨如何从零开始构建第一个安卓应用,并逐步深入到性能优化和高级功能的实现。无论你是编程新手还是希望提升技能的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
5天前
|
存储 API 开发工具
探索安卓开发:从基础到进阶
【10月更文挑战第37天】在这篇文章中,我们将一起探索安卓开发的奥秘。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和建议。我们将从安卓开发的基础开始,逐步深入到更复杂的主题,如自定义组件、性能优化等。最后,我们将通过一个代码示例来展示如何实现一个简单的安卓应用。让我们一起开始吧!
|
6天前
|
存储 XML JSON
探索安卓开发:从新手到专家的旅程
【10月更文挑战第36天】在这篇文章中,我们将一起踏上一段激动人心的旅程,从零基础开始,逐步深入安卓开发的奥秘。无论你是编程新手,还是希望扩展技能的老手,这里都有适合你的知识宝藏等待发掘。通过实际的代码示例和深入浅出的解释,我们将解锁安卓开发的关键技能,让你能够构建自己的应用程序,甚至贡献于开源社区。准备好了吗?让我们开始吧!
18 2
|
7天前
|
Android开发
布谷语音软件开发:android端语音软件搭建开发教程
语音软件搭建android端语音软件开发教程!