Android
文章平均质量分 82
zhaonhui
这个作者很懒,什么都没留下…
展开
-
Gradle8.0中Transform的替代方案
在Gradle插件中对HuiRouterApi进行插桩,添加插入路由信息的字节码指令,在程序运行时,插桩的字节码指令执行,路由信息被注册到HuiRouterApi内部的路由表中,然后外部就可以通过HuiRouterApi进行跳转操作了。扫描过程中,收集的路由信息记录到annotationPathMap中。5、在taskAction方法中,扫描遍历所有的jar和class文件,收集路由信息,查找到HuiRouterApi类,并将收集到的路由信息通过插桩的方式添加到HuiRouterApi中。原创 2023-10-16 22:00:32 · 1269 阅读 · 0 评论 -
基于Gradle8.0的插件开发
之前使用Groovy、Java 、 手动配置的方式演示了Gradle插件的整个自定义流程《自定义gradle插件》。本文使用java-gradle-plugin 和 Kotlin重新梳理下Gradle插件的自定义流程。1、新建一个Module模块hui_plugin(选择Kotlin Library)2、在hui_plugin模块的build.gradle.kts中引入“java-gradle-plugin” 和 “org.jetbrains.kotlin.jvm” 插件。原创 2023-10-09 23:09:53 · 2955 阅读 · 1 评论 -
LiveData的使用和原理
private val mutableLiveData = MutableLiveData<String>(); override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mutableLiveData.observe(this, Obser.原创 2020-10-10 21:13:04 · 1960 阅读 · 0 评论 -
Lifecycle的基本使用和原理
AppCompatActivity实现了LifecycleOwner接口,该接口有一个getLifecycle()方法,实现了这个接口的类就可以作为一个被观察者,被观察者观察它生命周期。@SuppressWarnings({"WeakerAccess", "unused"})public interface LifecycleOwner { Lifecycle getLifecycle();}在AppCompatActivity中调用getLifecycle方法返回的是LifeCycle的原创 2020-09-26 22:55:48 · 7377 阅读 · 0 评论 -
Java中的APT注解
java中常用的一些框架都使用到了注解,比如EventBus、Dragger2、Butterknife等,从这些流行框架可以看出,注解在Android中使用还是很广泛的,注解可分为运行时注解和编译期注解,运行时注解是通过反射在运行时拿到注解信息进行处理,编译期注解是在编译阶段根据注解生成相应的中间类来处理注解,因为运行时注解需要在运行时执行反射代码和注解处理逻辑,所以它的运行时性能没有编译期注解高,本文学习的注解方式就是APT编译时注解。一、创建一个名称为annotation的module单独存放自定义的原创 2020-08-05 09:30:54 · 844 阅读 · 0 评论 -
基于ndk-r21b编译ffmpeg-4.3.1
1、ffmpeg下载地址:http://ffmpeg.org/download.html打开下载地址选择需要的平台和版本号进行下载,下载可以先下载下来,然后在上传到linux上,也可以使用以下命令,在linux上直接下载:wget http://ffmpeg.org/releases/ffmpeg-4.3.1.tar.bz22、解压下载好的ffmpeg,解压命令如下:tar xvf ffmpeg-4.3.1.tar.bz23、解压后会生成一个解压目录ffmpeg-4.3.1,在这个目录下创建a原创 2020-07-31 09:30:40 · 1233 阅读 · 3 评论 -
Rxjava2中Single的map操作符源码学习
//注释1Single<Integer> integerSingle = Single.just(1);//注释2Single<String> stringSingle = integerSingle.map(new Function<Integer, String>() { @Override public String apply(Integer integer) { return "map:" + String.valueOf原创 2020-07-25 12:08:09 · 513 阅读 · 0 评论 -
Rxjava2中Single的just操作符源码学习
//注释1Single<Integer> integerSingle = Single.just(1);//注释2integerSingle.subscribe(new SingleObserver<Integer>() { @Override public void onSubscribe(Disposable d) { } @Override public void onSuccess(Integer s) {原创 2020-07-23 21:56:12 · 1273 阅读 · 0 评论 -
dex替换方式实现热修复
加载原理:BaseDexClassLoader、DexPathList、dexElements数组、findClass等一、下载修复的dex到手机上需要修复的dex是放到服务器上的,当App启动的时候就去下载到手机上(最好存放到应用私有目录下,这样更加安全,不容易被误删除,便于加载使用)。这里为了方便就省去了下载的过程,直接将修复包放到assets目录下了。然后将assets目录下的修复包复...原创 2020-05-07 22:21:01 · 901 阅读 · 0 评论 -
ASM和自定义Transform的应用实践
上篇文章学习了下如何自定义gradle插件《自定义gradle》,在实际应用中一般都会结合自定义的Transform和字节码操作框架(像ASM、Javassist)通过操作字节码来实现自己的业务逻辑,Transform是Android Gradle 在1.5.0 版本后提供的, 它允许第三方的Plugin插件在打包成 dex 文件之前的编译过程中操作 class 文件,对于一些重复性的操作,程序员...原创 2020-05-04 15:09:59 · 1354 阅读 · 0 评论 -
Android Studio3.6版本,格式化xml布局,导致错乱
将Android Studio升级到最新版3.6.3,编写完xml文件后,来了一下代码格式化,然后惊奇的发现布局全都乱套了,检查发现自己写的view控件位置发生了变化,不知道AS为什么会出现这么弱智的设计,下面说下解决问题的方法(Mac版):打开AS最上面的一行工具栏->Android Studio->PreferencesEditor->XML->Set from...原创 2020-04-30 11:41:14 · 1060 阅读 · 0 评论 -
自定义gradle插件
自定义gradle插件的方式有3种,第一种是直接创建build.gradle文件并在里面编写配置代码,第二种是在项目中新建一个buildSrc模块并在这个模块中编写groovy代码,第三种就是在独立的Module中编写插件,这里介绍的自定义插件采用的是第三种方式,具体的实现步骤如下:1、新建一个工程项目gradle_plugin_demo,然后在新建一个Module模块custom_plugin...原创 2020-04-27 23:06:04 · 2519 阅读 · 0 评论 -
自定义注解在MVP中的使用
P层添加注解原创 2020-04-25 11:52:04 · 315 阅读 · 0 评论 -
动态代理在MVP中的使用
动态代理原创 2020-04-16 10:38:53 · 418 阅读 · 0 评论 -
Retrofit源码解析
一、Retrofit创建过程源码解析 mRetrofit = new Retrofit.Builder() .baseUrl(HttpConfig.BASE_URL) // 设置网络请求的Url地址 .client(mOkHttpClient) .addConverterFactory(GsonCon...原创 2020-03-27 10:02:46 · 219 阅读 · 0 评论 -
OkHttp源码分析
一、OkHttp的基本使用//构建OkHttpClient对象OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(new RequestIntercept()) .readTimeout(5, TimeUnit.SECONDS) .writeTimeout(...原创 2020-03-08 15:24:52 · 234 阅读 · 0 评论 -
ContentProvider启动过程
getContentResolver()会调用到ContextWrapper的getContentResolver方法: @Override public ContentResolver getContentResolver() { return mBase.getContentResolver(); }mBase的实现类是ContextImpl,Conte...原创 2019-12-27 11:29:45 · 609 阅读 · 0 评论 -
广播的发送和接收过程
ContextWrapper:Context mBase; @Override public void sendBroadcast(Intent intent) { mBase.sendBroadcast(intent); }ContextImpl: @Override public void sendBroadcast(Intent inte...原创 2019-10-29 17:46:21 · 1685 阅读 · 0 评论 -
Android中VideoView播放视频不能充满屏幕以及视频上的view与视频不同步显示的问题
在做播放视频的时候,发现videoView不能充满整个屏幕,在布局中设置充满父窗体也不行,最后重写onMeasure解决了问题:public class FullScreenVideoView extends VideoView { public FullScreenVideoView(Context context) { super(context);原创 2016-08-23 08:53:04 · 6885 阅读 · 5 评论 -
Android中的DeepLink
DeepLink简单理解就是通过在手机上点击一个链接后实现如下功能:如果目标App没有启动,那么就拉起App,并跳转到App内指定页面如果目标App已经启动,那么就把App拉到前台并跳转到App内指定页面实现步骤1、提前定义好scheme,通过scheme匹配调起App2、在App的清单文件中对首页Activity进行scheme的配置,同时还要将首页Activity的启动模式设置为...原创 2018-12-23 21:41:17 · 3130 阅读 · 0 评论 -
Service的启动过程
Service的启动过程startService();ContextImpl原创 2019-05-23 23:46:35 · 404 阅读 · 0 评论 -
Context的创建过程
Context是Android中的上下文环境,页面跳转、开启服务、发送广播、弹框、访问资源、获取系统服务等等,很多的操作都需要Context。其中Activity、Service、Application都是Context的子类,一个应用中有多少个Context实例呢,一共有Activity个数+Service个数+Application个数(1个)。Activity的Context实例创建:p...原创 2019-09-02 22:25:40 · 1399 阅读 · 0 评论 -
Service的绑定过程
Service的绑定过程ContextWrapper类://Context类型,具体实现类是ContextImplContext mBase; @Overridepublic boolean bindService(Intent service, ServiceConnection conn, int flags) { return mBase.bindSer...原创 2019-09-09 14:36:25 · 2040 阅读 · 1 评论 -
Android中的Binder机制二(匿名Binder)
前言上篇文章讲了AIDL的基本使用《AIDL的使用》,本文在上篇文章的基础上从应用层面的角度,分析一下Binder通信的一个大概过程,文章中分析所用到的代码,都是上篇文章中的代码,这里就不在重复粘贴之前的代码了。基础概念在Android中的Binder机制中,主要涉及四部分系统组件,分别是Client、Server、ServiceManager、Binder驱动,其中Client、Serve...原创 2019-09-16 11:14:54 · 2060 阅读 · 0 评论 -
广播的动态注册过程
广播的动态注册过程广播注册代码BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //TODO 处理接收到的广播消息 }...原创 2019-09-23 10:16:08 · 1583 阅读 · 0 评论 -
adb不是内部命令或外部命令,也不是可运行的程序或批处理文件
在AndroidStudio的命令行里,使用adb命令操作安卓手机时,报“adb不是内部命令或外部命令,也不是可运行的程序或批处理文件“的错误,报这个错误是因为没有为adb配置环境变量,adb的环境变量配置跟java的配置是一样的,下面记录一下配置步骤。打开电脑属性,找到高级系统设置选项打开高级系统设置面板,选中高级选项,点击下面的环境变量打开环境变量面板,选中系统变量下面的path选项进...原创 2018-12-22 23:56:56 · 26059 阅读 · 0 评论 -
自定义View流程(结合源码分析)
一、View的绘制流程主要是:测量(measure)、布局(layout)、绘制(draw)三大流程。对于一个普通View(不是容器)主要是关心测量和绘制两个过程,测量可以确定自身的宽、高、大小,绘制可以显示出view的具体内容(呈现在屏幕上的)。对于ViewGroup(容器控件)主要是关心测量和布局两个过程,测量不仅仅要测量自身还要测量所有的子view,布局主要是指定所有子view在自...原创 2018-11-17 20:07:52 · 380 阅读 · 0 评论 -
自定义可滑动选择标签
在开发中,遇到这样一个需求,就是列表的头部有多行选择标签作为筛选条件,在网上找了一些指示器控件,有的需要跟ViewPager关联才能用,有的定制性不太好,所以就自己写了这样的一个控件,在这里记录一下,方便以后查看。效果图如下:实现思路是继承HorizontalScrollView,动态的管理其子View进行处理。主要涉及到三个类,LabelSelectView(核心功能实现)、LabelAda...原创 2018-11-22 23:34:03 · 945 阅读 · 0 评论 -
Android中的线程池
一、为什么要使用线程池 在Android开发中,所有的耗时任务都要放到子线程中去做,如果是自己去手动创建线程,那么就会出现线程数量过多、线程的频繁创建和销毁、线程难以管理等问题,使用线程池的优点可以总结为以下三点: 可以重用线程池中的线程,避免线程的创建和销毁引起的性能开销。可以有效控制线程池的最大并发数,避免大量的线程之间抢占系统资源而造成阻塞的现象。可以对线程进行管理...原创 2018-05-26 20:47:43 · 295 阅读 · 0 评论 -
Android下的事件分发机制(结合源码分析)
一、事件是由外向内传递的,下面的事件传递流程是A-B-C,A是最外层view,其次是B,最里层的是C,下面从B开始进行分析。 1、action_down事件到达B时,会调用B的dispatchTouchEvent方法,然后会在dispatchTouchEvent内部调用onInterceptTouchEvent方法判断是否要拦截事件。 2、如果onInterceptTouchE原创 2017-05-07 18:17:11 · 316 阅读 · 0 评论 -
解决LikeButton不兼容23以下版本的问题
解决网上实现点赞特效的一个项目,对23以下版本不兼容的问题,原项目链接:https://github.com/jd-alexander/LikeButton原创 2016-08-17 10:11:58 · 520 阅读 · 1 评论 -
解决阿里百川推送机型兼容问题
在集成阿里百川推送功能的时候,发现在小米手机和美图手机上测试正常,但是在华为手机上则初始化会失败。原因是百川推送sdk不支持64位JNI库,如果项目中有64位JNI库,碰上走64位的手机,就会出现该问题,解决办法是去除工程中的64位JNI包,走兼容包就可以了。原创 2016-08-17 14:27:20 · 1845 阅读 · 0 评论 -
Android录制视频,可限制时长,限大小
Android录制视频:public static void recordVideo(Context context, int limit_time, int size) { Intent intent = new Intent(); intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE); intent.putExtra原创 2016-08-26 11:48:54 · 7078 阅读 · 1 评论 -
TextView自定义省略号、部分文字变色、部分文字点击
TextView自定义省略号位置,文本中部分文字变颜色,可点击原创 2016-08-29 09:34:50 · 1927 阅读 · 0 评论 -
ExpandableTextView可以展开和收缩的TextView
基本使用:studio中直接引用 compile 'com.ms-square:expandableTextView:0.1.4',然后可以在代码中使用,用法和TextView一样。布局文件:xml version="1.0" encoding="utf-8"?>xmlns:android="http://schemas.android.com/apk/res/android"an原创 2016-08-29 09:52:24 · 665 阅读 · 0 评论 -
TextView换行居中,每行居中显示
textView默认换行是顶到textview的左边的,有时候需求会要求文本中的每行都是居中的,下面的代码可实现:public class CenterTextView extends TextView { private StaticLayout mStaticLayout; private TextPaint mTextPaint; public Center原创 2016-08-29 18:57:16 · 7161 阅读 · 1 评论 -
textView自动缩放字体大小
textView显示的宽度是一定的,如果字数过长就要缩小字体,以满足显示宽度,如果字数少,就要正常显示字体大小,可自定义textView实现,代码如下:public class AutoScaleTextView extends TextView { private static float DEFAULT_MIN_TEXT_SIZE = 0; private static原创 2016-08-29 19:01:00 · 5359 阅读 · 0 评论 -
Android中的消息机制一(Handler、Looper、ThreadLocal、MessageQueue)
每一个线程都对应一个自己的Looper,线程默认是没有Looper的,但是在应用启动的时候ActivityThread会初始化主线程的Looper,所以主线程是有Looper的,默认就可以使用Handler。Handler的作用是将一个任务切换到指定的某个线程中去执行。Handler创建时会使用当前线程的Looper,如果当前线程没有Looper就会报错。 Handler的构造方法: p...原创 2018-06-12 09:56:13 · 373 阅读 · 0 评论 -
Android中的消息机制二(Handler的工作过程)
上篇文章中介绍了Handler、Looper、ThreadLocal、MessageQueue这四个类,本文结合一个例子分析一下Handler的工作过程,假设有两个线程分别是Thread1和Thread2。Thread1代码:package com.example.lx_rl.handlerdemo;import android.os.Handler;import android...原创 2018-06-13 09:51:01 · 409 阅读 · 0 评论 -
Android中的消息机制三(主线程的消息模型、ANR问题)
主线程的消息处理Android中主线程的程序入口是ActivityThread类的main方法,main方法是一个静态方法,在main方法中会创建ActivityThread的实例对象,会创建主线程的Looper并开启Looper循环,main方法的源码如下: public static void main(String[] args) { ..................原创 2018-06-14 10:39:53 · 598 阅读 · 0 评论