Android清单文件详解(二) ---- 应用程序权限声明(二)

简介: Android清单文件详解(二) ---- 应用程序权限声明(二)

3.<uses-sdk>节点——SDK版本限定


大家都知道,软件对于平台版本是的一定要求的。如果平台版本能够达到软件运行的要求,那就能保证软件的稳定性。比如,大家都知道NFC功能是不能在Android 1.5中运行的,如果正在开发带类似功能的应用程序,那就必须对所在平台有所要求,而<uses-sdk>节点正是用来满足这种需求的。


<uses-sdk>节点使用一个整型值来表达应用程序与一个或多个Android平台版本的兼容性。值得注意的是,这些整型值代表的是API级别。应用程序给定的API级别将和一个给定Android系统的API级别做比较。当然,对于不同的Android设备,这可能会有所不同。需要说明的是,这个节点用于指定API级别,而不是用于指定SDK的版本号或Android平台的。


使用此节点的代码如下所示:


<uses-sdk android:minSdkVersion="integer"
android:targetSdkVersion="integer"
android:maxSdkVersion="integer"/>


①android:minSdkVersion:用于指定要运行应用程序所需的最小API级别。如果系统的API级别比该属性指定的值要小,则Android系统会阻止用户安装此应用。在大多数情况下,应指定这个属性。如果没有指定该属性,那么系统会认为此属性值为“1”。


②android:targetSdkVersion:用于指定应用程序的目标API级别。


③android:maxSdkVersion:指定最大的API级别。


4.<instrumentation>节点——应用的监控器


<instrumentation>节点用于监控应用程序与系统交互,它会在应用程序组件实例化之前被实例化。这个节点在多数情况下用于单元测试。其语法结构如下:

<instrumentation android:functionalTest=["true"|"false"]
android:handleProfiling=["true"|"false"]
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:targetPackage="string">


下面详细说明这些属性:


①android:functionalTest:标识这个Instrumentation类是否作为一个功能测试运行,它的默认值是false。


②android:handleProfiling:标识这个Instrumentation对象是否打开和关闭性能分析,它的默认值是false。


③android:icon:这个属性代表这个Instrumentation类的图标


④android:label:该属性是Instrumentation类的标题。


⑤android:name:该属性是Instrumentation子类的名称,是一个类的Java风格的名称,例如com.example.liyuanjinglyj.myInstrumentation。


⑥android:targetPackage:该属性是需要监控的目标应用程序名称,这个名称来自与目标应用程序AndroidManifest.xml中<manifest>节点的package属性值。


当然在eclipse需要专门创建一个测试项目,而且还要配置这个节点,但是在android studio并不需要这么做,考虑到2015年底谷歌不再支持eclipse,所以只讲解android studio单元测试,而讲解这个节点是因为到现在eclipse依然有大量的开发者使用,所以,讲解了节点的详细说明。


下面举例说明如何进行单元测试:


①创建项目,依然拿我们一直使用的HelloWorld做实验,你会发现项目目录里面有这样一个测试包:

55.png

②右键点击这个包,选择NEW-CLASS菜单项,新建MyFirstTest继承自ActivityInstrumentationTestCase2<T>,如下图所示:

package com.example.liyuanjing.helloworld;
import android.test.ActivityInstrumentationTestCase2;
/**
 * Created by liyuanjing on 2015/7/14.
 */
public class MyFirstTest extends ActivityInstrumentationTestCase2<MainActivity>{
    public MyFirstTest(){
        super(MainActivity.class);
    }
}


在这段代码中,ActivityInstrumentationTestCase2<T>中的<T>要换成我们测试的类,因为我们要测试MainActivity所以换成这个。


③我们测试内容为,在编辑框中输入一些字符,当点击按钮后,文本框等于编辑框输入的字符串,MainActivity代码如下:

public class MainActivity extends FragmentActivity {
    private static final String SDCARD= Environment.getExternalStorageDirectory()+File.separator;
    private FileFragment  fileFragment=new FileFragment();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(savedInstanceState==null){
            getSupportFragmentManager().beginTransaction().add(android.R.id.content,fileFragment).commit();
        }
    }
    public static class FileFragment extends Fragment {
        private View mRootView;
        public FileFragment(){}
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view=inflater.inflate(R.layout.file_fragment,container,false);
            final EditText myEdit=(EditText)view.findViewById(R.id.myEdit);
            final TextView content=(TextView)view.findViewById(R.id.content);
            Button myBut=(Button)view.findViewById(R.id.myBut);
            myBut.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    content.setText(myEdit.getText().toString());
                }
            });
            this.mRootView=view;
            return view;
        }
        public View getRootView(){
            return this.mRootView;
        }
    }
    public FileFragment getFragment(){
        return fileFragment;
    }
}


测试类的代码如下:

public class MyFirstTest extends ActivityInstrumentationTestCase2<MainActivity>{
    private TextView content;
    private EditText myEdit;
    private Button myBut;
    private MainActivity mainActivity;
    public MyFirstTest(){
        super(MainActivity.class);
    }
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        this.mainActivity=(MainActivity)getActivity();
        this.content=(TextView)this.mainActivity.getFragment().getRootView().findViewById(R.id.content);
        this.myEdit=(EditText)this.mainActivity.getFragment().getRootView().findViewById(R.id.myEdit);
        this.myBut=(Button)this.mainActivity.getFragment().getRootView().findViewById(R.id.mybut);
    }
    public void testButtonClick(){
        getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_H);
        getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_E);
        getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_L);
        getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_L);
        getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_O);
        getInstrumentation().waitForIdleSync();
        getInstrumentation().runOnMainSync(new Runnable() {
            @Override
            public void run() {
                myBut.performClick();
            }
        });
        getInstrumentation().waitForIdleSync();
        SystemClock.sleep(1000);
        assertEquals(this.content.getText().toString(),this.myEdit.getText().toString());
    }
}


注意:


Ⅰ在MyFirstTest类的构造放中,由于指定了被测试项目的Activity的详细信息,就使得MyFirstTest与Activity关联上。


ⅡsetUp()方法是一个重写的方法,它的作用是在测试前做必要的设置,比如实例化一些对象,打开网络等,它与tearDown()方法成对出现。这里我们没有实现tearDown()方法,当测试完成以后,框架会自动回调基类,也就是tearDown()方法。


最后,运行测试类,如下图所示:


56.png

当系统完成测试后,就可以在Android studio集成开发环境中得到下图所示的结果:

57.png

在图中可以看到,编写的Test测试类返回值为OK,这就证明测试达到了预期的目的。

相关文章
|
5月前
|
存储 Android开发
如何查看Flutter应用在Android设备上已被撤销的权限?
如何查看Flutter应用在Android设备上已被撤销的权限?
255 64
|
5月前
|
存储 Android开发 数据安全/隐私保护
如何在Android设备上撤销Flutter应用程序的所有权限?
如何在Android设备上撤销Flutter应用程序的所有权限?
330 64
|
5月前
|
缓存 Android开发 开发者
Flutter环境配置完成后,如何在Android设备上运行Flutter应用程序?
Flutter环境配置完成后,如何在Android设备上运行Flutter应用程序?
948 62
|
5月前
|
开发工具 Android开发 开发者
在Android设备上运行Flutter应用程序时,如果遇到设备未授权的问题该如何解决?
在Android设备上运行Flutter应用程序时,如果遇到设备未授权的问题该如何解决?
297 61
|
4月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
4月前
|
Java Android开发
Android studio中build.gradle文件简单介绍
本文解析了Android项目中build.gradle文件的作用,包括jcenter仓库配置、模块类型定义、包名设置及依赖管理,涵盖本地、库和远程依赖的区别。
390 19
|
4月前
|
存储 XML Java
Android 文件数据储存之内部储存 + 外部储存
简介:本文详细介绍了Android内部存储与外部存储的使用方法及核心原理。内部存储位于手机内存中,默认私有,适合存储SharedPreferences、SQLite数据库等重要数据,应用卸载后数据会被清除。外部存储包括公共文件和私有文件,支持SD卡或内部不可移除存储,需申请权限访问。文章通过代码示例展示了如何保存、读取、追加、删除文件以及将图片保存到系统相册的操作,帮助开发者理解存储机制并实现相关功能。
1065 2
|
7月前
|
移动开发 安全 Java
Android历史版本与APK文件结构
通过以上内容,您可以全面了解Android的历史版本及其主要特性,同时掌握APK文件的结构和各部分的作用。这些知识对于理解Android应用的开发和发布过程非常重要,也有助于在实际开发中进行高效的应用管理和优化。希望这些内容对您的学习和工作有所帮助。
674 83
|
移动开发 安全 Android开发
构建高效Android应用:Kotlin协程的实践与优化策略
【5月更文挑战第30天】 在移动开发领域,性能优化始终是关键议题之一。特别是对于Android开发者来说,如何在保证应用流畅性的同时,提升代码的执行效率,已成为不断探索的主题。近年来,Kotlin语言凭借其简洁、安全和实用的特性,在Android开发中得到了广泛的应用。其中,Kotlin协程作为一种新的并发处理机制,为编写异步、非阻塞性的代码提供了强大工具。本文将深入探讨Kotlin协程在Android开发中的应用实践,以及如何通过协程优化应用性能,帮助开发者构建更高效的Android应用。
|
API 调度 Android开发
打造高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第27天】在移动开发领域,性能优化和响应速度是衡量应用质量的关键因素。随着Kotlin语言的普及,协程作为其核心特性之一,为Android开发者提供了一种全新的并发处理方式。本文深入探讨了Kotlin协程在Android应用开发中的优势,并通过实例演示如何在实际项目中有效利用协程提升应用性能和用户体验。