Android - 小百科

Android Asset Studio

https://romannurik.github.io/AndroidAssetStudio/index.html

Android Studio Build Output 栏内汉字出现乱码的解决方案

https://blog.csdn.net/zhang5690800/article/details/104502632

Android 类的加载

Android: When do classes get unloaded by the system?

屏幕尺寸

How to Find Device Metrics for Any Screen

@hide在Android源代码中是什么意思?

Android有两种类型的API,无法通过SDK访问。

第一个位于package中com.android.internal。第二种API类型是用@hide Javadoc属性标记的类和方法的集合。

通过 lint 检查改进代码

静态代码lint常见报错处理

lint:lint 实用程序尝试检测命名的C程序文件的功能,这些功能可能是错误,不可移植或很浪费。它也比C编译器执行更严格的类型检查。lint实用程序在其第一阶段运行C预处理程序,其中处理器符号 “lint” 定义为允许lint更改或跳过某些可疑代码。因此,此符号应为被视为由lint检查的所有代码的保留字。

https://zh.wikipedia.org/wiki/Lint
https://www.unix.com/man-page/FreeBSD/1/lint

利用注释改进代码检查

经常见到的注释 suppressLint 表示抑制 Lint 对类或者方法的检测。

https://developer.android.com/studio/write/lint.html

注释处理器

注释处理器通过注解预编译的方式,可以根据源文件中的注释生成额外的源文件和其它的文件(文件具体内容由注释处理器的编写者决定),还可以编译生成的源文件和原来的源文件,将它们一起生成 class 文件。

过去使用 android-apt 插件的方式进行注解预编译,不过 APT(Annotation Processing Tool) 工具的作者宣布了不再维护该工具了,因此 Android Studio 推出了官方插件,并且可以通过 gradle 来简单的配置,它就是 annotationProcessor

免费图标

https://fonts.google.com/icons?selected=Material+Icons
https://icons8.cn/icon/pack/user-interface/material

专有名词

POM(Project Object Model,项目对象模型)

JBR 是指JetBrains Runtime,JetBrains Runtime是一个运行时环境,用于在Windows,macOS和Linux上运行基于IntelliJ Platform的产品。 JetBrains Runtime基于OpenJDK项目并进行了一些修改。 这些修改包括:亚像素抗锯齿(Subpixel Anti-Aliasing),Linux上的增强字体渲染,HiDPI支持,连字(ligatures),macOS上的San Francisco字体系列支持,官方构建中未提供的本机崩溃的一些修复,以及其他小的增强功能。

JetBrains Runtime与所有JetBrains IDE的最新版本捆绑在一起,默认情况下使用,除非执行显式重新配置。 例外是32位Linux系统,其中IDE需要单独的JDK安装,因为目前只捆绑了64位JetBrains Runtime。 对于Windows,捆绑了32位JetBrains Runtime,它可以在32位和64位系统上运行。

https://confluence.jetbrains.com/display/IDEADEV/JetBrains+Runtime+Environment

JUnit:JUnit是一个Java语言的单元测试框架。JUnit的体验对测试驱动开发是很重要的,所以一些 JUnit知识经常和测试驱动开发的讨论融合在一起。可以参考Kent Beck的 《Test-Driven Development: By Example》一书(有中文版和影印版)。

https://zh.wikipedia.org/wiki/JUnit

ABI:应用二进制接口。不同的Android手机使用不同的CPU,而不同的 CPU 支持不同的指令集,CPU 与指令集的每种组合都有专属的应用二进制接口,即 ABI。

CPU主要ABI支持的ABI
ARMv5armeabiarmeabi
ARMv7armeabi-v7aarmeabi ,armeabi-v7a
ARMv8arm64-v8aarmeabi ,armeabi-v7a,arm64-v8a
x86x86armeabi ,armeabi-v7a ,x86
x86_64x86_64armeabi ,x86 ,x86_64

https://www.jianshu.com/p/b17f9b926f2b

EABI:与关于通用计算机的ABI的主要区别是应用程序代码中允许使用特权指令,不需要动态链接(有时是禁止的),和更紧凑的堆栈帧组织用来节省内存(精简指令集)。广泛使用EABI的有Power PC和ARM(进阶精简指令集机器)

https://zh.wikipedia.org/wiki/%E5%BA%94%E7%94%A8%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%8E%A5%E5%8F%A3

QEMU(quick emulator)是一款由Fabrice Bellard等人编写的免费的可执行硬件虚拟化的开源托管虚拟机。 其与Bochs,PearPC类似,但拥有高速,跨平台的特性。

ETC1:Ericsson Texture Compression爱立信纹理压缩。

PKM文件格式:以16字节的标头描述图像边界,其次是编码的ETC1纹理数据。

ART

https://zh.wikipedia.org/wiki/Android_Runtime

Android Runtime(缩写为ART),是一种在Android操作系统上的运行环境,由Google公司研发,并在2013年作为Android 4.4系统中的一项测试功能正式对外发布,Android 4.4中带来的ART模式仅仅是ART的一个预览版,系统默认仍然使用的是Dalvik虚拟机;Android 5.0以后的ART运行时库有较大的不同,尤其体现在兼容性上,在Android 5.0及后续Android版本中作为正式的运行时库取代了以往的Dalvik虚拟机。

ART能够把应用程序的字节码转换为机器码,是Android所使用的一种新的虚拟机。它与Dalvik的主要不同在于:Dalvik采用的是JIT(即时编译)技术,而ART采用Ahead-of-time(AOT)技术。ART同时也改善了性能、垃圾回收(Garbage Collection)、应用程序出错以及性能分析。

JIT:在应用程序启动时,JIT通过进行连续的性能分析来优化程序代码的执行,在程序运行的过程中,Dalvik虚拟机在不断的进行将字节码编译成机器码的工作。

AOT:在应用程序安装的过程中,ART就已经将所有的字节码重新编译成了机器码。应用程序运行过程中无需进行实时的编译工作,只需要进行直接调用。因此,ART极大的提高了应用程序的运行效率,同时也减少了手机的电量消耗,提高了移动设备的续航能力,在垃圾回收等机制上也有了较大的提升。

ELF:为了保证向下兼容,ART使用了相同的Dalvik字节码文件(dex),即在应用程序目录下保留了dex文件供旧程序调用,然而.odex文件则替换成了可执行与可链接格式(ELF)可执行文件。一旦一个程序被ART的dex2oat命令编译,那么这个程序将会指通过ELF可执行文件来运行。因此,相对于Dalvik虚拟机模式,ART模式下Android应用程序的安装需要消耗更多的时间,同时也会占用更大的内部储存空间,用于储存编译后的代码,但节省了很多Dalvik虚拟机用于实时编译的时间。

颜色对照表

颜色对照表

Context

https://developer.android.com/reference/android/content/Context

java.lang.Object
   ↳	android.content.Context

getSupportFragmentManager:获取应用的 Fragment 管理器,可以访问所有的 Fragment
getContentResolver:内容共享,可对数据进行 CRUD 操作
getSystemService:可用以获得 Wifi、窗口、状态栏等服务,进而获得它们的管理器,eg:NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE)

全局获取 Context

public class GetContextApplication extends Application {
    private static Context context;

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }

    public static Context getContext() {
        return context;
    }
}

Application

https://developer.android.com/reference/android/app/Application

java.lang.Object
   ↳	android.content.Context
 	   ↳	android.content.ContextWrapper
 	 	   ↳	android.app.Application

Activity

  1. 在希望传送的 Activity 中定义 Activity 启动方式、参数。优点:减少耦合,启动方主动提供参数

BookAddActivity.class:

// 请求 BookAddActivity 的模板
public static void actionStart(Activity activity, String category) {
    Intent intent = new Intent(activity, BookAddActivity.class);
    intent.putExtra("category", category);
    activity.startActivityForResult(intent, 2333);
}
  1. 使用 getIntent 获得启动此 Activity 的意图,从中获取传递的数据
  2. 生命周期 onStart 完成后可见,数据生成可在延时线程进行

BaseActivity 能在 debug 时看到生命周期:

public class BaseActivity extends AppCompatActivity {
    public String TAG = this.getClass().getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.e(TAG, "onCreate: BEFORE");
        super.onCreate(savedInstanceState);
        Log.e(TAG, "onCreate: AFTER");
    }

    @Override
    protected void onStart() {
        Log.e(TAG, "onStart: BEFORE");
        super.onStart();
        Log.e(TAG, "onStart: AFTER");
    }

    @Override
    protected void onResume() {
        Log.e(TAG, "onResume: BEFORE");
        super.onResume();
        Log.e(TAG, "onResume: AFTER");
    }

    @Override
    protected void onPause() {
        Log.e(TAG, "onPause: BEFORE");
        super.onPause();
        Log.e(TAG, "onPause: AFTER");
    }

    @Override
    protected void onStop() {
        Log.e(TAG, "onStop: BEFORE");
        super.onStop();
        Log.e(TAG, "onStop: AFTER");
    }

    @Override
    protected void onDestroy() {
        Log.e(TAG, "onDestroy: BEFORE");
        super.onDestroy();
        Log.e(TAG, "onDestroy: AFTER");
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
        Log.e(TAG, "onCreateView A: BEFORE");
        View view = super.onCreateView(name, context, attrs);
        Log.e(TAG, "onCreateView A: AFTER");
        return view;
    }

    @Nullable
    @Override
    public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
        Log.e(TAG, "onCreateView B: BEFORE");
        View view = super.onCreateView(parent, name, context, attrs);
        Log.e(TAG, "onCreateView B: AFTER");
        return view;
    }
}

Service

BaseService 能在 debug 时看到生命周期:

public class BaseService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Undefine Binder");
    }

    @Override
    public void onCreate() {
        Log.d(getClass().getSimpleName(), "onCreate");
    }

    @Override
    public void onDestroy() {
        Log.d(getClass().getSimpleName(), "onDestroy");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(getClass().getSimpleName(), "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(getClass().getSimpleName(), "onUnbind");
        return super.onUnbind(intent);
    }
}

进程

AndroidManifest.xml 的 activity 中添加 android:process=":XXX" 属性

其中:":Name" 表示当前应用私有进程,完整名称为 “应用包名:Name”

“包名.Name” 表示全局进程,可以外部访问

Intent

  • 使用 getDoubleExtra 需要设定 defaultValue,设为 0.00
  • Bundle 相当于 Map,使用键值保存信息
  • 需要使用 getSerializationExtra,可以通过 implications Serialization 实现类的序列化
  • 可以使用隐式 Intent 进行选择浏览器打开、拨号等活动,需要匹配 Android 内置动作和类型才可以接收请求
  • setPackage 可以指定去往特定应用的组件,为 null 则考虑所有应用的所有组件

其他

  1. 无论创建哪种 UI 组件,都需要传入一个 Context 参数,通过其获取 Android 应用环境的全局信息
  2. 使用 MyGetContextApplication 获取当前 context
  3. 使用 CopyOnWriteArrayList<E> 可以对 ArrayList<E> 进行并发同步处理
  4. 使用 mHandler.obtainMessage(int what, Object obj) 简化代码
  5. 获取线程:Thread.currentThread().getName()
  6. Canvas(画板)对象获取方法有两种:一是通过重写 View.onDraw 方法,View 的 Canvas 会以参数的形式传递进来;二是创建对象:
Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Cnofig.ARGB.8888);
Canvas c = new Canvas(b);
  1. setColorFilter (ColorFilter colorFilter):如果Drawable具有ColorFilter,则Drawable的绘图内容中的每个输出像素在混合到Canvas的渲染目标之前都将被滤色器修改。ColorFilter直接使用其子类构造函数BlendModeColorFilter(int color, BlendMode mode)、ColorMatrixColorFilter、LightingColorFilter、PorterDuffColorFilter(int color, PorterDuff.Mode mode),其中BlendMode
    不包含 alpha 通道因素,PorterDuff.Mode
    包含 alpha 通道因素。参考Android-使用 SetColorFilter 神奇地改变图片的颜色

编程技巧

在不确定使用范围时,都声明为 private 类型,由于 private 类型范围小,更容易受限制,可根据编译器提示更改

try…catch…finally 的 finally 无论是否异常都会执行,没有 finally,无异常继续执行 try…catch 后面代码,有异常则在 catch 中处理,有 finally 则可执行两种情况都需要执行的代码,减少代码输入

内容共享

获取共享数据处理
  1. 申请权限,进行动态处理
  2. 写 Uri,参数:Context,Authority,FilePath
  3. 使用 ContentResolver 进行CRUD、读写(eg:openInputStream(Uri))操作
提供数据共享
  1. 新建一个类 extends ContentProvider
  2. 重写方法,其中 getType 用以匹配 Uri
  3. 使用静态方法创建一个 UriMatchr 实例并赋值,使用请求码在 getType 中判断 MIME 类型地址返回
  4. AndroidManifest.xml 在 application 中加入 provider 标签对新建类进行注册

服务

使用原装开发

drawable

图标
xml 中使用:android:src="@android:drawable/ic_menu_add"
代码中使用:setImageResource(android.R.drawable.ic_menu_add)

上:android.R.drawable.ic_media_previous
快退:android.R.drawable.ic_media_rew
播放:android.R.drawable.ic_media_play
暂停:android.R.drawable.ic_media_pause
快进:android.R.drawable.ic_media_ff
下:android.R.drawable.ic_media_next

layout

简单的列表项布局:android.R.layout.simple_list_item_1
简单的可选列表项布局:android.R.layout.simple_list_item_checked

tools:context=".MainActivity" 的作用

TextView 采用了 android :text , 而 EditText中使用了 tools:text ,右边Layout 编辑器会显示内容Name , sample name 两个 字体, 如果你运行代码后编译,生成apk 后,终端就只显示Name,不会显示Sample Name这个字样. 大家可以试试运行,看下效果就知道。。

( 比如我们在布局TextView 中想要显示一段文字时,以前使用android:text显示,然后在编译器中布局调整,最后完成后删除android:text属性。有了tools参数后,可以直接使用tools:text在预览时显示文字即可,省却了上面删除的麻烦,编译后此tools:text 相当于注释了。)

讲到这里,我们回去继续理解:tools:context 属性

  1. tools:context="activity name"这一句不会被打包进APK,

    –> 理解:相当于这句被注释了,编译后不起任何作用.

  2. 只是ADT的Layout Editor(即为上面图示右边模拟器)在当前的Layout文件里面设置对应的渲染上下文,当前的布局xml所在的渲染上下文是activity name对应的那个activity,如果这个activity在manifest文件中设置了Theme,那么ADT的Layout Editor会根据这个Theme来渲染你当前的Layout。就是说如果你设置的MainActivity设置了一个Theme.Light(其他的也可以)。

    –>理解:你加上了tools:context=“activity name” ,这个xml 布局就是渲染指定activity , manifest文件中设置了Theme 的话, 上图右边模拟器theme 样式也会跟着变化对应 theme。

————————————————
原文链接:https://blog.csdn.net/xiabing082/article/details/50563559

DDMS

DDMS 的全称是Dalvik Debug Monitor Service,是Android 开发环境中的Dalvik虚拟机调试监控服务。 它为我们提供例如:为测试设备截屏,针对特定的进程查看正在运行的线程以及堆信息、Logcat、广播状态信息、模拟电话呼叫、接收SMS、虚拟地理坐标等等。

Tombstone 墓碑文件

当系统 crash 的时候,会保存一个 tombstone 文件到 /data/tombstones 目录下(Logcat 中也会有相应的信息),文件的确就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。

https://www.cnblogs.com/CoderTian/p/5980426.html

JNI 和 NDK 的关系

JNI 是 Java 本地接口,实现与底层 C/C++ 代码的交互,使得跨平台的 Java 拥有适应平台的能力;

NDK 是本地开发工具包,是 Android 适应平台的开发工具,能将 JNI 开发的 .so 和应用一起打包成 APK。

Android:JNI 与 NDK到底是什么?(含实例教学)

测试

Instrumentation

实现应用程序代码检测的类。在打开检测的情况下运行时,此类在任何应用程序代码之前实例化,从而使您可以监视系统应用程序之间的所有交互。

https://developer.android.com/reference/android/app/Instrumentation.html

AndroidJUnitRunner

AndroidJUnitRunner 类是一个 JUnit 测试运行程序,可让您在 Android 设备上运行 JUnit 3 或 JUnit 4 型测试类,包括使用 Espresso 和 UI Automator 测试框架的测试类。

使用 AndroidJUnitRunner 版本 1.0 或更高版本时,您可以使用一个名为 Android Test Orchestrator 的工具,从而让应用的每个测试在其自己的 Instrumentation 调用中运行。

要使用 Gradle 命令行工具来启用 Android Test Orchestrator,请完成以下步骤:

将以下语句添加到项目的 build.gradle 文件:

android {
  defaultConfig {
   ...
   testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

   // 以下参数使Android Test Orchestrator在每次测试调用后均运行“ pm clear”命令,保证测试之前完全清除了上次应用测试的状态。
   testInstrumentationRunnerArguments clearPackageData: 'true'
 }

  testOptions {
    execution 'ANDROIDX_TEST_ORCHESTRATOR'
  }
}

dependencies {
  androidTestImplementation 'androidx.test:runner:1.1.0'	// AndroidJUnitRunner 所在库
  androidTestUtil 'androidx.test:orchestrator:1.1.0'
}

通过执行以下命令来运行 Android Test Orchestrator:

./gradlew connectedCheck

https://developer.android.com/training/testing/junit-runner

Espresso

您可以使用 Espresso 来编写简洁、美观且可靠的 Android 界面测试。

以下代码段展示了 Espresso 测试的一个示例:

@Test
public void greeterSaysHello() {
    onView(withId(R.id.name_field)).perform(typeText("Steve"));
    onView(withId(R.id.greet_button)).perform(click());
    onView(withText("Hello Steve!")).check(matches(isDisplayed()));
}

核心 API 小巧、可预测且易于学习,但仍可进行自定义。Espresso 测试会清楚地说明预期、交互和断言,让您不受样板内容、自定义基础架构或杂乱的实现细节干扰。

Espresso 测试运行速度极快!当它在静止状态下对应用界面进行操纵和断言时,让您无需等待、同步、休眠和轮询。

目标受众群体:Espresso 面向认为自动化测试是开发生命周期不可或缺的一部分的开发者。虽然 Espresso 可用于黑盒测试,但熟悉被测代码库的人员可以开启它的全部功能。

https://developer.android.com/training/testing/espresso

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值