SnapHelper通过调用attachToRecycleview方法,将recycleview对象传递到封装类SnapHelper里面。
内部调用了Recycleview.addOnScrollListener 和 setOnFlingListener 方法用来监听我们recycleview滑动。
1 | // Recycleview.java |
1 | // java |
SnapHelper通过调用attachToRecycleview方法,将recycleview对象传递到封装类SnapHelper里面。
内部调用了Recycleview.addOnScrollListener 和 setOnFlingListener 方法用来监听我们recycleview滑动。
1 | // Recycleview.java |
1 | // java |
在反编译比较大得apk得时候会遇到一些问题:
比如:java.lang.RuntimeException: can not merge I and Z
解决办法:android 反编译出错 can not merge I and Z - lianghe - 博客园 (cnblogs.com) 替换掉lib文件里面的dex-ir-2.0.jar架包。架包下载路径:链接:https://pan.baidu.com/s/1tYKlC6czgNKk6b_zf1j6Yw 提取码:4djc
然后我们需要下载比较新的dex2jar-2.0工具包:
下载链接:Releases · pxb1988/dex2jar (github.com)
以上工具主备好了就可以进行反编译了:Android开发学习总结(六)—— APK反编译 - 孤傲苍狼 - 博客园 (cnblogs.com)
第一步:这里需要在手机装一个虚拟机:下载链接Releases · android-hacker/VirtualXposed (github.com) 直接下载apk进行安装就好了。
第二部:写模块:
1 | <!--添加表示 这是一个插件--> |
在build.gradle添加xposed得api依赖:
1 | provided 'de.robv.android.xposed:api:82' |
新建assets文件,新建文件xposed_init,并写入hook代码得入口文件
新建hook得入口类 XposedHook
1 | public class XposdHook implements IXposedHookLoadPackage { |
完成
关于xposed得api接口说明网址:XC_MethodHook | Xposed Framework API
下载网址:
然后等待安装就好。
需求描述:进行网络请求,然后展示数据。
这是最常用的,最基本的一个LiveData
继承自MutableLiveData。它可以观察其他的LiveData对象,并对来自它们的OnChanged事件做出反应。用来合并多个LiveData的值,并且统一做出回应。
例子:
1 | var liveData1:LiveData = ...; |
androidx.lifecycle:lifecycle-livedata-ktx:2.3.1
这是一个内部类,我们没法直接使用。使用方法直接通过 liveData() 的方式进行创建。注意:在liveData()创建一个livedata的时候,他的内部block会在livedata为活跃状态下自动触发。然后需要通过emit或者emitSource方式把结果发送出去。
通过名字就可以知道这是一个具有协程属性挂起的livedata,通过它可以发送延迟的数据,并且他也是和生命周期绑定的。因为使用它只能通过 liveData()这个方法创建,我们就来分析这个:
1 | public fun <T> liveData( |
构建一个LiveData,其中包含在LiveDataScope上执行的给定块产生的值。当返回的LiveData变为活动时,块开始执行。如果在块执行时,LiveData变为非活动状态,它将在timeoutInMs毫秒之后被取消,除非LiveData在该超时之前再次变为活动状态(以优雅地处理活动旋转等情况)。LiveDataScope任何值。从已取消的块发出的将被忽略。取消之后,如果LiveData再次激活,则将从头重新执行该块。如果你愿意的话。
那这个timeoutInMs是怎么起作用的呢。这里看源码:
在CoroutineLiveData类里面的onInactive(非活跃)方法:
1 | internal class CoroutineLiveData<T>( |
案例:
1 | val data : LiveData<Int> = liveData { |
1 | // 一个基于' userId '获取' User '对象并每30秒刷新一次的LiveData |
1 | // A retrying data fetcher with doubling back-off |
1 | // a LiveData that tries to load the `User` from local cache first and then tries to fetch |
1 | // a LiveData that immediately receives a LiveData<User> from the database and yields it as a |
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串,判断字符串是否有效。
有效字符串需满足:
解题思路:遍历字符串当符合( { [ 这些字符串的时候就进行压栈,当不等于这些的时候就从栈顶拿一个出来和当前的值进行比较。
答:
1 | fun main() { |
数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。
例子:
1 | 输入 n = 3 |
这里可以发现。每次节点都有两种可能,要么是左括号,要么是右括号。并且还可以发现规律,当右括号的数量大于左括号的数量的时候,是不成立的的。所以咱们可以使用递归:
1 | public class Soulution{ |
使用DataBing如果只是想展示数据的话,你的数据类就和常规的一样就好了。如果你想ui监听到你的数据改变的话,你的数据类就需要继承类BaseObservable,参数需要用@Bindable进行声明。
1 | class Student : BaseObservable { |
使用@Bindable声明的参数我们在类BR可以找到生成的对应参数名子:
1 | public class BR { |
数据变化我们需要调用notifyPropertyChanged(propertyId) 或者 notifyChange()。一个是指针对某一个id进行更新,一个是针对全部的数据进行更新。
1 | class Student : BaseObservable { |
1 | ssh-keygen -t ed25519 -C "你的邮箱" |
在Ubuntu系统上保存位置: 根目录./ssh
把 .pub 文件内容 填到github里面:
1 | // 查看内容 |
把key添加到ssh agent上,由于默认使用的是.ssh/id_rsa,所以你需要显示告诉ssh agent加上新的key
1 | ssh-add ~/.ssh/id_ed25519 |
想要查看的话执行:ssh-add -l
因为是多账户所以要配置.ssh/config
一般默认没有config文件,需要手动创建 touch config
1 | $ vi .ssh/config |
到这里git的配置完成了。
可以进行远程测试:
1 | $ ssh –T github-A |
将代码进行上传,这里有一点需要注意,我们远程的写法需要改变。需要填上刚才配置config的HOST的名字:
原来的写法
1 | $ git clone git@github.com: 11699/learngit.git |
现在
1 | $ git clone git@github-B:librityYu/Whatif.git |
还想在完美点可以给仓库设置单独的用户名:
1 | $ git config user.name "one_name" ; git config user.email "one_email" |
在kotlin里面代理都是通过by关键字来实现得。代理顾名思义就是重写setValue方法和getValue方法,将某一类型得数据按照我们设计好的某种工厂方式加工出来。比如by lazy,我们希望使用他的代理都可以实现懒加载得功能,帮助开发者省下每次都要写懒加载得方式。
实现代理得思路就是重写setVaule方法和getValue方法。如果是var声明的变量那么就可以重写setValue和getValue。如果是val声明的就只能重写getValue。当然我们还可以自定义提供委托需要重载方法provideDelegate操作符。可以扩展创建属性实现所委托对象的逻辑。
这里先来演示一个简单的,代理getVaule和setValue:
1 | import kotlin.reflect.KProperty |
属性委托要求:
对于val: 委托必须提供一个操作符函数 getValue(),该函数具有以下参数:
thisRef —–必须与属性所有者类型(对于扩展属性–指被扩展的类型)相同或者是其超类
property—— 必须是类型
KProperty<*>` 或其超类型。
1 | class Resource |
对于var委托必须额外提供一个操作符函数 setValue()
, 该函数具有以下参数:
thisRef
—— 必须与 属性所有者 类型(对于扩展属性——指被扩展的类型)相同或者是其超类型。property
—— 必须是类型 KProperty<*>
或其超类型。value
— 必须与属性类型相同(或者是其超类型)。1 | class Resource |
provideDelegate
的参数与 getValue
相同:
thisRef
—— 必须与 属性所有者 类型(对于扩展属性——指被扩展的类型)相同或者是它的超类型;property
—— 必须是类型 KProperty<*>
或其超类型。例子:
1 | import kotlin.properties.ReadOnlyProperty |
1 | private fun onLogoutAndRestartApp() { |
1 | package com.lin.baselib.util; |