节选自:Java注解代码生成
1、简介
在我们常用的框架中注解和自动生成代码的身影很常见,因为注解和自动生成的配合,从而简化和统一代码,使框架使用简单且容易扩展,典型且最熟悉的就是ButterKnife,主要功能利用注解省略了findViewById的过程,当然也提供了其他的监听、绑定等很多强大的操作符,熟悉ButterKnife源码的应该知道,ButterKnife的实现就是利用我们今天的要讲的内容,我们在文章的最后也会尝试编写一个简单的ButterKnife;
节选自:Java注解代码生成
1、简介
在我们常用的框架中注解和自动生成代码的身影很常见,因为注解和自动生成的配合,从而简化和统一代码,使框架使用简单且容易扩展,典型且最熟悉的就是ButterKnife,主要功能利用注解省略了findViewById的过程,当然也提供了其他的监听、绑定等很多强大的操作符,熟悉ButterKnife源码的应该知道,ButterKnife的实现就是利用我们今天的要讲的内容,我们在文章的最后也会尝试编写一个简单的ButterKnife;
节选自:IjkPlayer 学习笔记
笔记可能微乱,但大致清晰,可能会对他人有所帮助,故分享出来。
×××××××××××××××目录×××××××××××××××
ijk概述
mediacodec相关
OpenGL相关
filter相关
setOption配置相关
metadata相关
h264编码器特有的设置域
线程相关
消息机制
音频输出
声道切换
SDL_CreateCond 与 SDL_CreateThreadEx
如何暂停
×××××××××××××××××××××××××××××××××
节选自:手机设备信息与 Android build.prop 文件
路径: /system/build.prop
说明: build.prop
是 Android 系统中的一个重要的属性文件,记录了系统的设置和改变。
主要信息类型:ro.build.*
(编译信息),ro.product.*
(设备信息),ro.config.*
(默认设置信息),dalvik.vm.*
(虚拟机信息)等。
一种是通过访问 /system/build.prop
文件进行查看
# 打印 /system/build.prop 所有内容 adb shell cat /system/build.prop # 通过 grep 筛选特定内容 adb shell cat /system/build.prop | grep ro.product
也可以用 ADB 的命令查看
# 显示所有信息 adb shell getprop # 显示特定信息 adb shell getprop ro.product.model # 筛选信息 adb shell getprop | grep product
参数 | 说明 | 例子 |
---|---|---|
ro.build.id | 编译标识 | ro.build.id=KTU84P |
ro.build.display.id | 显示标识 | ro.build.display.id=KTU84P release-keys |
ro.build.version.sdk | 编译时使用的SDK版本 | ro.build.version.sdk=19 |
转载自:Android 开发之ActivityLifecycleCallback
ActivityLifecycleCallbacks是Application里的一个接口,在Android4.0(API level 14)中新加。用于监听应用中所有Activity的生命周期的调用情况,callback中的方法会在Activity回调方法之前调用,可以通过实现这个接口来完成一些特殊需求,比如检测APP是否处于前台。
以检测APP是否处于前台为例介绍使用。
public class ActivityLifecycleCallbackWrapper implements Application.ActivityLifecycleCallbacks { private static final String TAG = "LifecycleCallback"; private int count; private boolean isForeground; public boolean isForeground() { return isForeground; } @Override public void onActivityCreated(Activity activity, Bundle bundle) { //to do } @Override public void onActivityStarted(Activity activity) { count ++; } @Override public void onActivityResumed(Activity activity) { //to do } @Override public void onActivityPaused(Activity activity) { //to do } @Override public void onActivityStopped(Activity activity) { count --; if(count == 0) { isForeground = true; } } @Override public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { //to do } @Override public void onActivityDestroyed(Activity activity) { //to do } }
public class MyApplication extends Application { ActivityLifecycleCallbacks callbacks; @Override public void onCreate() { super.onCreate(); callbacks = new ActivityLifecycleCallbackWrapper(); registerActivityLifecycleCallbacks(callbacks); // 注册Callback } }
ViewBindingUtil
import android.view.LayoutInflater; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.viewbinding.ViewBinding; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Objects; public class ViewBindingUtil { public static <Binding extends ViewBinding> Binding create(Class<?> clazz, LayoutInflater inflater) { return create(clazz, inflater, null); } public static <Binding extends ViewBinding> Binding create(Class<?> clazz, LayoutInflater inflater, ViewGroup root) { return create(clazz, inflater, root, false); } @SuppressWarnings("unchecked") @NonNull public static <Binding extends ViewBinding> Binding create(Class<?> clazz, LayoutInflater inflater, ViewGroup root, boolean attachToRoot) { Class<?> bindingClass = getBindingClass(clazz); Binding binding = null; if (bindingClass != null) { try { Method method = bindingClass.getMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class); binding = (Binding) method.invoke(null, inflater, root, attachToRoot); } catch (Exception e) { e.printStackTrace(); } } return Objects.requireNonNull(binding); } private static Class<?> getBindingClass(Class<?> clazz) { ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass(); Type[] types = Objects.requireNonNull(parameterizedType).getActualTypeArguments(); Class<?> bindingClass = null; for (Type type : types) { if (type instanceof Class<?>) { Class<?> temp = (Class<?>) type; if (ViewBinding.class.isAssignableFrom(temp)) { bindingClass = temp; } } } return bindingClass; } }
BaseActivity
import android.os.Bundle; import android.view.LayoutInflater; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.viewbinding.ViewBinding; public abstract class BaseActivity<Binding extends ViewBinding> extends AppCompatActivity { protected Binding binding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ViewBindingUtil.create(getClass(), LayoutInflater.from(this)); setContentView(binding.getRoot()); } }
参考链接:
在项目根目录的build.gradle文件中添加以下内容
buildscript { repositories { maven { url 'https://maven.aliyun.com/repository/google/' } maven { url 'https://maven.aliyun.com/repository/public/' } } } allprojects { repositories { maven { url 'https://maven.aliyun.com/repository/google/' } maven { url 'https://maven.aliyun.com/repository/public/' } } }
关于ViewBinding的文档,官方写的很详细,请看视图绑定。本文一切从简,主要说下Google官方没有提到的一些问题。
ViewBinding支持按模块启用,在模块的build.gradle文件中添加如下代码:
android { ... viewBinding { enabled = true } }
//之前设置视图的方法 setContentView(R.layout.activity_main); //使用ViewBinding后的方法 mBinding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(mBinding.getRoot());
本文将介绍在Android Studio中,android单元测试的介绍和实现。相关代码托管在github上的AndroidJunitDemo中,涉及到的用例代码收集于google官方提供的测试用例android-testing,同时进行了简化和修改。你可以从该demo中学习单元测试简单的使用,在工程中,包含两个模块,一个实现计算器功能的CalculationActivity,另外一个是PersonlInfoActivity,可以编辑姓名,邮箱和生日等信息,并保存到SharePreferences中,同时提供了两个模块的单元测试。
关于单元测试,在维基百科中,给出了如下定义:
在计算机编程中,单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。
android中的单元测试基于JUnit,可分为本地测试和instrumented测试,在项目中对应
以上分别执行在JUnit和AndroidJUnitRunner的测试运行环境,两者主要的区别在于是否需要android系统API的依赖。
在实际开发过程中,我们应该尽量用JUnit实现本地JVM的单元测试,而项目中的代码大致可分为以下三类: