《Monkey Android》第5课之剖析第一个App

本文深入解析Android应用开发中的三个关键文件:MainAcitivity.java、activity_main.xml和AndroidManifest.xml,详细解读其作用及代码含义,为初学者提供清晰的入门指南。

转发请注明出处:
安卓猴的专栏(http://blog.youkuaiyun.com/androidmonkey)


通过本节课可以学习到的内容:

  • 第一个App最重要的三个文件
  • MainAcivity.java代码分析
  • activity_main.xml代码分析
  • AndroidManifest.xml代码分析

最重要的三个文件

我们的第一个项目FirstDemo.java建立以后,Android Studio首先展示给我们的就是activity_main.xmlMainAcivity.java源文件,
另外,还有一个无比重要的文件AndroidMenifest.xml,下面我们着重理解这三个文件的作用以及代码的含义。

MainAcivity.java代码分析

顾名思义,Main的意思是主要的Acivity的意思是活动;那么,MainAcivity.java源文件的作用肯定就是:

主要的活动窗口。

贴一下它的主要代码:

public class MainActivity extends AppCompatActivity {

    /**
     * Activity启动的时候调用
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

它有以下关键点:

  • 1.MainActivity继承自类AppCompatActivity,它是做什么的?

  • 2.有一个复写(Override)的方法onCreate,为什么要复写它呢?

  • 3.setContentView()方法又是做什么的呢?

  • 4.R.layout.activity_main是什么意思?

AppCompatActivity

从名字来看,Compat的意思是兼容,那么它的意思是App兼容Activity

Android有很多版本,因此,Google为了向下兼容更多的版本,提供了很多兼容包兼容类

我们来跟踪一下AppCompatActivity的源码:

  • 1.键盘长按Ctrl键,鼠标左键点击AppCompatActivity,AS会带我们来到AppCompatActivity类所在的源码位置;

  • 2.我们发现,AppCompatActivity继承自FragmentActivity,继续跟踪下去,键盘长按Ctrl键,鼠标左键点击FragmentActivity

  • 3.我们来到了FragmentActivity所在源码的位置,惊奇的发现,原来它们都是继承自Activity

现在我们弄清楚Activity是做什么的:

An activity is a single, focused thing that the user can do. Almost all activities interact with the user, so the Activity class takes care of creating a window for you in which you can place your UI with setContentView(View).

我给翻译一下就是:

所有在App中能看到的和做的都是在Activity上。

onCreate

当Activity运行的时候,首先会调用这个方法,在它里面,需要用setContentView()方法来设置UI布局。
另外,布局中的各种控件,都是在这里初始化的。

setContentView

setContentView() 用来给Activity设置一个UI布局,即activity_main.xml,有了它,我们的App才能显示出各种各样的界面。

R.layout.activity_main

R是编译器为我们自动生成的一个文件,它里面是各种控件、布局等等的ID值,layout表示所引用的activity_main是一个布局文件,位于工程目录layout文件夹下。

activity_main.xml代码分析

贴一下源码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>
  • RelativeLayout用来表示,这个一个相对布局,里面的控件都是按照相对的位置来拜访的,除此之外还有多种布局,以后会讲到;

  • xmlns:android="http://schemas.android.com/apk/res/android"是命名空间,有了它,就可以引用Android给我们提供好的控件属性;

  • layout_width表示布局的宽,layout_height表示布局的高,有3种值:match_parent撑满父布局,wrap_content包裹内容,具体的数值例如200dp;

  • 对于TextView来说,它是用来显示文本内容的,因此它有一个属性text,显示的内容是strings.xml文件中的键为hello_world的值,也可以直接在”“中写上内容,不过不推荐;

  • android:id=”@+id/textview”表示该TextView的id是textview,方便在Java代码中进行实例化初始化;

  • @表示通过一个id引用一个内容,@+表示增加一个id;

  • 将android:text=”@string/hello_world”改为android:text=”Hello 安卓猴”,再次运行下App看下效果。

AndroidManifest.xml代码分析

贴一下源码:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sunjiajia.firstdemo" >

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

顾名思义,由于manifest是清单的意思,所以AndroidManifest.xml就是Android清单文件,所有的Android四大组件都必须在这里进行声明。

  • android:icon表示App的图标;
  • android:label表示App的标签,即名称;
  • android:theme表示App的主题,不同个App有不同个样式主题,我们可以设置喜欢的主题;
  • activity是四大组件之一,因此它毫不犹豫的出现在了这里;
  • android:name表示activity的名字,例如MainActivity.java这个主Activity的name就是”.MainActivity”,.表示包名目录的根目录;
  • intent-filter标签里面定义了一个action和一个category,action表示此Activity的动作是MAIN,就是主界面,第一个Activity;category表示此Acivity是一个启动器,
    显示在Launcher中;
  • action和category同时作用表示该activity是App启动时加载的第一个Activity。

下课

学习了本节课程,相信一定能够大致懂得第一个App里面不同文件的作用,为自己写出代码作铺垫。

有什么问题请在下面留言评论,我们一起进步!

<think> 我们正在编写一个用于OPPO手机进行Monkey测试的cmd脚本,目标是随机测试所有APP。 根据引用内容,我们知道Monkey测试是Android自带的压力测试工具,通过发送随机事件流来测试应用。 步骤概述: 1. 获取手机上所有已安装的APP包名(因为Monkey测试需要指定包名)。 2. 针对每个包名执行Monkey测试,或者我们可以使用一个方法同时测试所有APP(注意:Monkey通常一次只能测试一个APP,但我们可以循环测试所有APP)。 但是,引用[3]提到:通过命令`adb shell dumpsys package`获取APP包名,并重定向到文件。我们可以使用类似方法获取所有包名。 然而,需要注意的是,Monkey测试通常是针对一个特定的包名(即一个应用)进行的。如果我们想测试所有APP,那么我们需要循环遍历每一个APP包名,然后分别对每个APP运行Monkey测试。 另外,引用[4]提到了Monkey测试的基本过程,包括获取包名和使用monkey测试。 因此,脚本步骤: 1. 通过adb连接设备(确保已开启USB调试)。 2. 获取设备上所有第三方APP的包名(或者包括系统APP?根据需求,如果测试所有APP,则包括系统APP,但通常我们只测试自己开发的APP或第三方APP,系统APP可能不需要测试。这里用户要求“所有APP”,所以包括系统APP,但注意系统APP可能无法测试或导致系统异常,需谨慎)。 3. 循环遍历每一个包名,执行Monkey命令。 但是,Monkey测试如果对所有APP(包括系统核心APP)进行随机事件测试,可能会导致手机系统不稳定甚至崩溃。因此,通常建议只测试自己开发的APP或指定的第三方APP。 由于用户要求OPPO手机随机测试所有APP,我们按照需求来,但需要提醒用户风险。 如何获取所有APP包名? 使用命令:`adb shell pm list packages` 可以得到所有包名。 然后,我们遍历这些包名,对每个包名执行Monkey命令。 Monkey命令示例: `adb shell monkey -p <package_name> -v 1000` (1000是事件数量,可根据需要调整) 但是,测试所有APP可能会花费很长时间,特别是当APP很多的时候。因此,我们可以选择设置每个APP测试的事件数少一点,或者只选取部分APP(比如非系统APP)进行测试。 由于用户要求所有APP,我们就不做过滤。 另外,引用[4]提到了日志分析,所以我们需要将日志保存下来。 因此,脚本逻辑: 1. 创建目录保存日志(比如在C盘创建monkey_logs目录)。 2. 获取设备上所有包名。 3. 遍历包名,对每个包名执行: adb shell monkey -p <package_name> -v 1000 > C:\monkey_logs\<package_name>_log.txt 这里事件数1000只是示例,用户可调整。 但是,注意:Monkey测试可能会被某些APP的安全机制拦截,或者在某些界面无法执行(比如锁屏界面),所以测试前需要确保手机屏幕常亮,并且解锁。 另外,为了能够长时间测试,最好让手机保持充电状态。 编写cmd脚本(批处理文件): 我们将编写一个.bat文件。 注意:在批处理中,循环遍历每一行(每个包名)并执行命令。 获取包名的命令:`adb shell pm list packages` 会输出如:package:com.example.app 这样的行,所以我们需要提取冒号后面的部分。 批处理中提取包名可以使用for循环的切分。 但是,考虑到包名可能很多,且批处理处理大量数据可能较慢,但通常可以接受。 具体脚本如下: 步骤: 1. 创建日志目录(如果不存在)。 2. 获取当前时间,用于生成日志文件名(可选,避免重复)。 3. 获取包名列表。 4. 循环处理每个包名。 注意:有些包名可能是系统核心包,测试可能导致系统异常,所以用户需要自行承担风险。我们可以在脚本中跳过某些包(比如设置为黑名单),但用户要求所有,所以先不做过滤。 但是,我们可以在日志中记录哪些包测试失败,以便后续分析。 由于Monkey测试可能因为APP没有启动界面(比如服务型APP)而失败,我们可以忽略这些错误。 下面是一个示例脚本(monkey_test_all.bat): ```batch @echo off setlocal enabledelayedexpansion REM 设置日志目录 set LOG_DIR=C:\monkey_logs REM 创建日志目录 if not exist "%LOG_DIR%" mkdir "%LOG_DIR%" REM 设置事件数量 set EVENT_COUNT=100 REM 获取当前时间,用于日志文件名 set TIMESTAMP=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2% set TIMESTAMP=%TIMESTAMP: =0% REM 获取设备上所有包名,并保存到临时文件 adb shell pm list packages > "%LOG_DIR%\all_packages.txt" REM 循环读取临时文件中的每一行 for /f "tokens=2 delims=:" %%a in ('type "%LOG_DIR%\all_packages.txt"') do ( set package=%%a REM 去除包名中的空格和回车 set package=!package: =! echo Testing package: !package! REM 对每个包执行monkey测试,并将日志输出到文件 adb shell monkey -p !package! -v %EVENT_COUNT% > "%LOG_DIR%\!package!_%TIMESTAMP%.log" 2>&1 ) echo Monkey test finished. Logs are saved in %LOG_DIR%. endlocal ``` 说明: 1. 事件数量设置为100(%EVENT_COUNT%),这是为了演示,实际使用时可以根据需要调整(比如1000或5000)。 2. 日志文件命名:包名_时间戳.log 3. 2>&1 表示将错误输出也重定向到同一个日志文件。 4. 我们使用`delims=:`来分割每一行,因为包名在“package:”后面。 5. 注意:有些包名可能含有空格,但我们使用`set package=!package: =!`去除了空格(实际上包名不会有空格,但为了安全还是去掉)。另外,换行符已经被for命令处理,所以不需要额外处理。 注意事项: 1. 确保手机已连接,且adb可用。 2. 确保手机屏幕解锁并亮屏(如果手机有锁屏,测试可能会中断)。 3. 测试过程中,手机可能会弹出各种界面,导致测试无法正常进行(比如权限请求、崩溃对话框等)。因此,建议在开发者选项中开启“不锁定屏幕”和“保持唤醒状态”。 4. 测试系统核心APP可能导致手机无响应或重启,请谨慎。如果用户确实需要测试所有APP,包括系统APP,那么接受风险。 改进建议: 1. 可以添加黑名单机制,跳过某些已知系统核心包(如com.android.systemui)以避免系统崩溃。 2. 可以增加超时机制,避免某个APP测试时间过长。 但是,由于用户要求所有APP,我们这里不添加黑名单。用户可以根据需要修改脚本。 另外,OPPO手机可能有自己的系统限制,比如后台活动限制、电池优化等,可能会影响Monkey测试。因此,需要在设置中关闭电池优化,并允许USB调试的权限。 最后,用户运行此脚本前,请确保只有一个设备连接(或者使用adb -s指定设备)。 如果用户需要测试多个设备,可以修改脚本以支持多设备,但本脚本只针对一个设备。 现在,我们提供这个基础脚本,用户可以根据实际情况调整。 </think> 以下是针对OPPO手机编写Monkey测试所有APP的CMD脚本方案,结合引用内容和Android测试规范: ### 脚本实现方案 ```batch @echo off REM 创建日志目录 mkdir C:\monkey_logs 2>nul REM 获取所有APP包名列表 adb shell "pm list packages -3" > C:\monkey_logs\package_list.txt REM 循环测试每个APP for /f "tokens=2 delims=:" %%i in (C:\monkey_logs\package_list.txt) do ( echo 正在测试: %%i adb shell monkey -p %%i --throttle 100 -s 12345 --ignore-crashes --ignore-timeouts --ignore-security-exceptions -v 5000 > C:\monkey_logs\%%i.log 2>&1 echo 测试完成: %%i >> C:\monkey_logs\summary_report.txt ) echo 所有APP测试完成!日志已保存至C:\monkey_logs ``` ### 关键参数说明 1. **包名获取** `pm list packages -3`:仅获取第三方应用(排除系统应用)[^3][^4] * 如需包含系统应用:移除`-3`参数 2. **Monkey核心参数** ```mathematica -p %%i // 指定测试包名 --throttle 100 // 事件间隔100ms(防界面卡顿) -s 12345 // 随机种子(可复现测试) --ignore-crashes // 忽略崩溃继续测试 --ignore-timeouts // 忽略ANR继续测试 -v 5000 // 执行5000个随机事件[^1][^2] ``` 3. **日志管理** `> C:\monkey_logs\%%i.log 2>&1`:合并标准/错误输出到日志文件 `summary_report.txt`:记录测试完成的应用清单 ### OPPO手机特殊配置 1. **开启开发者选项** `设置 → 关于手机 → 连续点击版本号7次` 2. **开启USB调试** `设置 → 系统设置 → 开发者选项 → USB调试` 3. **关闭优化设置** `设置 → 电池 → 应用耗电管理 → 选择待测APP → 允许后台运行`[^4] ### 执行步骤 1. 将脚本保存为`monkey_test.bat` 2. 手机开启USB调试并连接电脑 3. 双击运行脚本 4. 查看`C:\monkey_logs`中的日志文件 > 注意事项:测试期间保持屏幕常亮,避免锁屏中断测试。若测试系统应用,移除`pm list packages`中的`-3`参数[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值