bdmh
多年从事软件开发工作,现在主要从事移动端应用开发
展开
-
Android:registerForActivityResult
中我们提到过Fragment中的onActivityResult已经废弃了,推荐使用registerForActivityResult去注册一个ActivityResultContract契约,从而启动一个forResult的Activity来达到目的,所以这里就看看这个流程是如何进行的。在MainActivity执行commitNow的时候,就会执行到Fragment的performAttach方法,这里改变了mState的值。对于接收返回的result,道理类似,大家可以根据断点堆栈了解一下。原创 2024-01-23 10:49:56 · 609 阅读 · 0 评论 -
Android:FragmentActivity
平时我们在Fragment中startActivityForResult一个Activity后,会使用onActivityResult来接受返回结果,那么在较新的androidx中,Fragment中的相关操作已经废弃,虽然还能用,但已经提供了更好的接口去实现了。FragmentActivity中其它的方法,基本都是和生命周期相关,也比较常见,比如onCreate,onCreateView,onResume等,大家自己看看就能理解了。上面这些代码,大家打上断点,操作过程中就会看到它的来龙去脉。原创 2024-01-03 09:55:21 · 705 阅读 · 0 评论 -
Android:FragmentHostCallback
对于这几个属性是如何传进来的,就要说到FragmentHostCallback的子类HostCallbacks,HostCallbacks是FragmentActivity的内部类,FragmentActivity中有一个属性,会自动创建HostCallbacks对象。官方的说明如下,它整合了Fragment持有者的操作,Fragment可能被任何对象持有,比如Activity,为了管理这些Fragments,提供该类,重写方法去适配持有者。这样整个流程就通下来了,包括权限的申请回调也在这里。原创 2023-12-12 10:28:22 · 222 阅读 · 0 评论 -
Android:BackStackRecord
BackStackRecord:fragment回退栈,继承自FragmentTransaction,并且实现了OpGenerator接口,OpGenerator接口用来添加或弹出事务的,后面会提到。大家注意第一行代码,判断事务是否提交,已经提交就会抛出异常,而mCommitted被置位true以后,是不会再有置为false的机会了,所以如果你重复使用同一个事务进行commit,那么第二次必然报错。commit,非立即生效,事务会被添加到队列,交由FragmentHostCallback( 《原创 2023-11-30 16:40:28 · 272 阅读 · 0 评论 -
Glide:EngineResource
这个队列是用来创建ResourceWeakReference对象的,是对EngineResource的弱引用。EngineResource是一个资源包装器,实现Resource接口,运行资源计数。在ActiveResources中,有对它的引用队列。先来看看EngineResource的属性。原创 2022-11-14 10:18:23 · 313 阅读 · 0 评论 -
Glide:DecodeJob
参阅这个类的作用是,对缓存中数据或者原始资源进行解码、转换等操作,可以理解为一个作业,由EngineJob启动,内部通过相关对象对资源进行处理。先来看一下内部的枚举定义。DecodeJob在Engine中的waitForExistingOrStartNewJob方法中,由DecodeJobFactory创建,并执行DecodeJob的init方法。init方法中会初始化decodeHelper对象。原创 2022-11-09 10:30:06 · 385 阅读 · 0 评论 -
Glide:DecodeHelper
这个过程会传入一堆的参数,如用来加载图像的组件的长和宽,缓存策略,资源对象类型,优先级等等,就不再一一说明了。DecodeHelper是作为解码作业DecodeJob的助手类,用来获取解码相关对象或属性信息的。它的初始化方法init是在DecodeJob的init中调用的。这个类里包含两个枚举类型。原创 2022-10-27 15:03:27 · 323 阅读 · 0 评论 -
Glide:EngineJob
EngineJob这个类是用来通过添加和移除回调,来管理一个load过程,当load完成时,通知回调。EngineJob是在Engine类中,通过EngineJobFactory创建的。参考。先来看看EngineJob中的属性。ResourceCallbacksAndExecutors是一个内部类,管理资源加载的回调和相关线程。实现了Iterable接口。内部有一个List集合。用来保存ResourceCallbackAndExecutor对象(注意这个末尾不带“s”)。原创 2022-10-20 15:31:15 · 501 阅读 · 0 评论 -
Glide:ActiveResources
文章中,我们多次看到了ActiveResources这个对象,我们可以理解为活动的资源,今天就来分析一下ActiveResources的代码。这是一个同步方法,根据key,先从弱引用队列中移除掉该资源,并返回该资源。如果这个资源存在,则执行资源重置。资源监听是被定义在 EngineResource类中,Engine实现了这个接口。ResourceWeakReference 是一个内部类,维护弱引用资源对象。来看activeResources.deactivate。原创 2022-10-14 14:24:25 · 191 阅读 · 0 评论 -
Glide:Engine
这篇文章就来介绍一下Engine 这个类。Engine是负责开始加载和管理活动的以及在缓存中的资源。它实现以下三个接口。分别看一下这这三个接口。原创 2022-10-12 14:31:42 · 191 阅读 · 0 评论 -
Glide:Registry
在上一篇中,我们提到了,通过自定义的Module,可以替换掉Glide默认的组件,比如网络框架,这里就涉及到Registry这个类了。Registry这个类是用来管理Glide中注册的组件的,比如加载、解码、编码等,可以扩展和替换。我们先来看看它里面有些什么。这里只介绍各自负责的功能,具体的代码会陆续讲解。上面这些目前还是比较晦涩的,后面会慢慢展开来讲。Registry对象是在Glide的构造方法中创建的。我们看看Registry的构造方法。原创 2022-10-11 14:17:07 · 132 阅读 · 0 评论 -
Glide:AppGlideModule
上面代码中,getAnnotationGeneratedGlideModules方法就是创建GeneratedAppGlideModuleImpl这个类的,GeneratedAppGlideModuleImpl类自动生成的位置在build目录下。开发人员就可以自己去控制了。那GeneratedAppGlideModuleImpl这个类是什么时候被用到的呢,我们回到Glide.java中,加入我们使用下面代码。加入我也不想用okHttp,我想自己写一个网络请求,让Glide使用可不可以,当然可以。原创 2022-10-10 14:52:10 · 403 阅读 · 0 评论 -
Glide:GlideBuilder
annotationGeneratedModule 是可以通过注解方式,自动创建的,用户可以通过自定义的Module来设置一些选项或者注册自己的组件,比如使用自己的网络组件,这个后面会讲。Builder中的这些设置,我们都可以通过自定义的AppGlideModule子类的applyOptions方法进行设置。从名字看,大家应该不会感到陌生,这是Android中经常会遇到的Builder模式,它为Glide提供了默认的配置。这些过程完成后,就会调用Builder的build方法创建Glide实例了。原创 2022-10-09 14:32:51 · 267 阅读 · 0 评论 -
初始化:Glide.java
该方法,返回RequestManagerRetriever对象,RequestManagerRetriever是一个提供了一些静态方法,用来创建com.bumptech.glide.RequestManager实例,并可以在activity和fragment中检索对应的com.bumptech.glide.RequestManager对象。在Glide内部,定义了一个私有的静态变量glide,看上面的代码就很清楚的看到,Glide内部使用的是单例模式。在get方法中,使用了检测双锁的机制,来创建单例。原创 2022-10-09 14:32:36 · 292 阅读 · 0 评论 -
Glide环境搭建
当然如果我们要对Glide做一些全局的设置,或者替换已有的框架,比如想把网络框架替换为自己的(如okhttp,volley等),这些后面会陆续讲解。上面就是一个最基本的应用,从网络下载一个图像,然后显示到imageView中。使用Glide,需要引入几个包,在gradle文件中引入。有了上面的内容,Glide最常用的功能就可以使用了。Glide.with有很多重载,后面我们会详细说。这些设置在RequestOptions中体现。Glide的gitHub地址。原创 2022-10-09 14:32:16 · 395 阅读 · 0 评论 -
Java:对象池Pools
当我们创建了一些对象,又希望在某些时候重复使用,这样可以避免对象的频繁创建和引起垃圾回收,提高使用效率。这时,对象池就可以帮我们处理这个事情了。比如创建了几个数组,那我可以先把他们保存起来,需要使用时,从池子里取出来,存放新的数据或者复用数据都是可的。对象池的代码也相对简单,具体来看一下:Pools是一个final类。它里面有一个接口。Pools.java文件中包含两个静态类。原创 2022-10-17 16:02:41 · 480 阅读 · 0 评论 -
Android:ChildHelper的Bucket
RecyclerView,Bucket,位运算原创 2022-09-20 15:32:41 · 152 阅读 · 0 评论 -
Android:RecyclerView的ChildHelper
RecyclerView作为我们常用的数据列表展示组件,它可以包含若干的子视图(child),那就会涉及到添加、删除、隐藏、查找等等操作,所以Android SDK提供了一个专门负责管理RecyclerView子视图的类,就是ChildHelper类。今天我们就来看看ChildHelper的源码实现。它的官方说明如下:大概的意思就是说,ChildHelper是用来管理子视图的,它包含一对子视图的操作功能。原创 2022-09-19 09:51:27 · 660 阅读 · 0 评论 -
supportRequestWindowFeature(AppCompatActivity)
AppCompatActivity,标题栏,Actvity原创 2022-06-02 09:21:58 · 505 阅读 · 0 评论 -
Java:ArrayBlockingQueue
ArrayBlockingQueue是一个有界队列,执行先进先出(FIFO)原则,它是固定大小的,一旦创建,容量就不能被修改。先对部分属性和方法进行简单说明。属性items 内部保存对象的数组,这个数组创建后,大小就不会改变了,即使添加和取出元素,都不会影响数组大小,只不过对应位置会被改写 takeIndex 下一个被检索的元素的索引,初始为0,每取出一个元素,+1 putIndex 下一个被添加的元素的索引,初始为0,每添加一个元素,+1 count 队列的数量原创 2021-12-16 14:37:29 · 1332 阅读 · 0 评论 -
Java:ThreadPoolExecutor中的Worker
在文章《从源码看ThreadPoolExecutor的执行步骤》中已经讲过了ThreadPoolExecutor的执行步骤,里面提到了一个内部类Worker,它就是负责具体执行任务的,今天就来说说它。private final class Worker extends AbstractQueuedSynchronizer implements Runnable{ //worker的工作线程,如果创建失败则为null final Thread thread;原创 2021-12-14 09:45:51 · 353 阅读 · 0 评论 -
Java:从源码看ThreadPoolExecutor的执行步骤
提起线程,几乎每个人都知道,但是真正使用线程的确实不多。线程让许多人感到畏惧。在平时的工作中,使用线程,很多时候就是new一个Thread去start,当看到线程池ThreadPoolExecutor创建时的一堆参数,更是一头雾水。接下来的内容,我们就从源码看看ThreadPoolExecutor的工作流程,让你感到其实它很友好????。先看一张ThreadPoolExecutor的工作步骤图。我们来创建一个线程池的执行代码。int taskCount = 41;AtomicInte原创 2021-12-13 16:22:45 · 476 阅读 · 0 评论 -
Android:从源码看onSaveInstanceState的调用条件
Called to retrieve per-instance state from an activity before being killed so that the state can be restored in onCreate or onRestoreInstanceState (the Bundle populated by this method will be passed to both).This method is called before an activity may ..原创 2021-12-08 10:44:09 · 142 阅读 · 0 评论 -
Android:Instrumentation
先看一下官方的对Instrumentation的说明:Base class for implementing application instrumentation code. When running with instrumentation turned on, this class will be instantiated for you before any of the application code, allowing you to monitor all of the interact原创 2021-12-07 09:26:21 · 2835 阅读 · 0 评论 -
Android:ActivityTaskManagerService接管ActivityManagerService
ActivityManagerService这个服务,对于玩Android的开发人员,应该再熟悉不过了,它是掌管Activity的核心。不过从Android 10.0(API 29)开始,再看ActivityManagerService的代码,会发现,ActivityManagerService的工作已经被ActivityTaskManagerService这个服务接管了。具体我们就看看这里的变化。虽然说ActivityTaskManagerService接管了ActivityManagerServ原创 2021-12-01 16:50:28 · 3799 阅读 · 0 评论 -
Android:EditText长按选词的过程
在前面我们研究过下面两篇文章:《看看Android源码中View是如何实现LongPress的》《Java:BreakIterator是如何取词的》那么在Android组件EditText中,当我们点击在某个文字位置时,长按,就会选中匹配的词语。如图:这个过程其实就是上面两篇文章内容的综合运用,下面我们就来看看实现过程。既然是在长按事件中触发的,那就直接定位到TextView的performLongClick方法,如果是EditText,则TextView中的如下变量可用.原创 2021-11-29 14:46:30 · 2558 阅读 · 0 评论 -
Java:BreakIterator是如何取词的
BreakIterator是Java提供的一个用来判断语言边界的类。给定一个字符串和一个索引位置,BreakIterator可以根据本地语言边界限定规则,找到这个索引前后,可以和它组成词语或句子的字符的索引,我们可以根据begin和end索引来获取这个单词。比如下面的字符串:Hello World当指定索引8时,也就是字符o和r之间时,用BreakIterator去分词,就可以得到World这个单词。看下面的图就能看到了。BreakIterator提供了四种边界判断getWord.原创 2021-11-25 10:37:11 · 837 阅读 · 1 评论 -
看看Android源码中View是如何实现LongPress的
除了最常用的点击事件(Click),还有一个长按事件(LongPress),比如长按弹出复制、粘贴的菜单,长按弹出自定义View等等。这篇文章我们就来看看Android源码中是如何实现长按事件的。既然是手势动作,那就逃不过onTouchEvent。直接找到View代码中的onTouchEvent。这个时间里面,首先会检查几个是否可点击的状态,比如点击、长按、环境点击(触笔、鼠标右键等)。final boolean clickable = ((viewFlags & CLICKABLE)原创 2021-11-23 09:19:06 · 1946 阅读 · 0 评论 -
Android:从源码看权重Weight的计算
一个Layout中,放置几个TextView,然后对每个TextView设置不同的宽度比例,设置权重属性layout_weight就是我们最常用的一个功能。弄明白权重的计算,有助于我们更精准的布局。假设有如下布局,我们考虑子控件的width都是match_parent,权重比为1:2:2。屏幕宽度为1080。 <LinearLayout android:layout_width="match_parent" android:layout_height="原创 2021-11-19 16:36:29 · 1167 阅读 · 0 评论 -
Android:ArrowKeyMovementMethod
我们之前在Android:MovementMethod,BaseMovementMethod和Android:LinkMovementMethod、ScrollingMovementMethod两篇文章中讲过TextView的两种MovementMethod的工作过程,这两种都是针对TextView而言的,那么对应可选择文本或者EditText,还有一种MovementMethod,那就是Arro...原创 2020-04-09 13:58:49 · 787 阅读 · 1 评论 -
Android:TextView的AutoSizeText实现过程
在实际开发中,我们经常会遇到,TextView区域固定,但字数不确定,又希望把文字信息都展示出来,IOS中可以轻松实现,但在Android上好想并没有这种实现。从8.0(API26)开始,TextView组件提供了autoSizeTextType、autoSizeMinTextSize、autoSizeMaxTextSize等相关属性,来满足这个需求,在8.0以前的版本,可以通过com.and...原创 2020-03-06 12:32:07 · 2147 阅读 · 0 评论 -
Android:看看Google工程师的手误
我们启动Activity,都会用到Intent,Intent需要传入Context参数,通常我们在Activity中使用Intent时,都会传入Activity的实例作为Context。但由于考虑到内存泄漏的风险,大都提倡使用ApplicationContext,所以很多同学就把Activity类型的Context换成了ApplicationContext,这时就发现,突然不能正常启动Activi...原创 2020-03-04 15:49:58 · 404 阅读 · 0 评论 -
Serializable是怎么工作的(反序列化)
在《Serializable是怎么工作的(写入)》篇文章中,我们大致了解了Serializable的写入过程,我们用到的是ObjectOutputStream,那与之对应的就是反序列化,把存入文件的二进制数据,读出来,转换为对应的实例对象,这次就该用到ObjectInputStream了。使用代码大致如下:TesyBean sBean = new TesyBean();String pat...原创 2020-03-03 10:15:03 · 282 阅读 · 0 评论 -
Serializable是怎么工作的(写入)
Serializable是Java提供的数据序列号接口,只要你的Bean继承自Serializable接口,那么就可以被序列化保存到介质中或者进行数据的传输。当我们查看Serializable的代码时,就会发现,里面什么都没有,那Java是如何处理继承了Serializable接口的数据呢?public interface Serializable {}既然Serializable...原创 2020-03-02 13:47:17 · 383 阅读 · 0 评论 -
从源码看int和Integer的面试题
int是一种基本数据类型,Integer是一个对象,需要实例化才能使用。它对int进行了包装,在Integer内部有一个对应的数值int变量。private final int value;int和Integer的对比,经常被拿来作为面试题,下面就多种情况,通过源码分析其结果。我们将比较“==”和Equals两种结果。第一种情况:Integer i1 = new Integer(...原创 2020-02-25 10:13:05 · 322 阅读 · 1 评论 -
Android:LinkMovementMethod、ScrollingMovementMethod
再上一篇文章《MovementMethod,BaseMovementMethod》中我们讲了Movement的基类,这里我们讲一下它的子类LinkMovementMethod和ScrollingMovementMethod,为什么把它俩放到一起呢?因为LinkMovementMethod继承自ScrollingMovementMethod。先来看ScrollingMovementMethod。...原创 2020-02-21 11:34:23 · 2631 阅读 · 2 评论 -
Android:MovementMethod,BaseMovementMethod
我们在使用TextView,EditText等组件时,可以会有光标的显示,可以选择文本,拖动轨迹球,滚动,长按弹出菜单等操作,这些都是MovementMethod的作用。MovementMethod是一个接口,提供了光标的位置、滚动以及文本的选择等操作。它会处理按键及Touch等操作。这个接口仅供系统调用。先来看看这个接口里面有哪些方法。//这里做一些初始化的工作public vo...原创 2020-02-11 14:57:32 · 1588 阅读 · 1 评论 -
Android:Parcelable序列化读写过程(Parcel)
Parcelable是为Android量身定制的序列化接口,底层是C的实现,通过内存来操作数据。Android中通过Binder机制传递Parcelable数据。Parcelable是一个接口,需要序列化的对象必须实现这个接口。而具体负责数据组装的是Parcel类。接下来,我们就以Activity间通过Intent传递序列化对象,来看看Parcel的工作过程。整个流程涉及到Activity...原创 2020-01-14 10:31:04 · 854 阅读 · 0 评论 -
Java:源码分析—反射(Method、Field)
在上一篇文章Java:源码分析—反射(实例化对象:newInstance)中我们了解了反射进行对象实例化的过程,既然对象有了,我们就要使用它,对于一个对象,我们最常用的就是方法和属性里,所以这一篇我们就来看看反射中的Method和Field。在Class.java文件的代码中,比较常用的关于方法和属性的是getMethods、getDeclaredMethods、getFields、getDe...原创 2020-01-09 09:54:17 · 387 阅读 · 0 评论 -
Java:源码分析—反射(实例化对象:newInstance)
今天我们来通过源代码,看看Java中反射是如何工作的。反射,其实在我们日常的编程过程中可能用的并不多,但是第三方的库,这个技术确实应用非常广泛的,包括我们在开发Android应用时,有时为了操作一些不开放的系统属性时,也会用到反射。这里我们将通过分析反射的运行,来看看Class这个类的功能。开始之前,先提到两个静态的整型变量,在java.lang.reflect.Member中。这两个变量...原创 2020-01-08 13:45:15 · 1017 阅读 · 0 评论