
android
Android 开发笔记
hswizy
这个作者很懒,什么都没留下…
展开
-
Android Tapjacking
android 安全原创 2022-08-10 15:17:56 · 1095 阅读 · 0 评论 -
Kotlin For 循环
fun main() { // 循环包含开头和结尾的数据 for (i in 0..10) { print("$i ") } // 0 1 2 3 4 5 6 7 8 9 10 println() // 倒序循环包含开头和结尾的数据 for (i in 10 downTo 0) { print("$i ") } // 10 9 8 7 6 5 4 3 2 1 0 println()原创 2022-03-22 15:02:57 · 4408 阅读 · 0 评论 -
协程timeout和suspendCoroutine
kotlin.runCatching { withContext(Dispatchers.IO) { withTimeout(2100) { suspendCancellableCoroutine<String> { Thread.sleep(3000) logger("time continue") it.resumeWith(Result.succe原创 2022-01-17 15:47:07 · 1971 阅读 · 0 评论 -
Android 为ImageView 添加点击效果
android:background="?attr/selectableItemBackgroundBorderless"原创 2021-11-26 11:02:40 · 1963 阅读 · 0 评论 -
ROOM 为字段添加唯一索引
@Entity(indices = {@Index(value = {"first_name", "last_name"}, unique = true)}) public class User { @PrimaryKey public int id; @ColumnInfo(name = "first_name") public String firstName; @ColumnIn...原创 2021-11-22 13:28:26 · 2609 阅读 · 0 评论 -
EventBus、Rxbus、LiveBusEvent
EventBusEventBus2.x使用的是运行时注解,它采用了反射的方式对整个注册的类的所有方法进行扫描来完成注册,因而会对性能有一定影响。EventBus3.x使用的是编译时注解,Java文件会编译成.class文件,再对class文件进行打包等一系列处理。在编译成.class文件时,EventBus会使用EventBusAnnotationProcessor注解处理器读取@Subscribe()注解并解析、处理其中的信息,然后生成Java类来保存所有订阅者的订阅信息。这样就创建出了对文件或类的原创 2021-11-11 14:32:35 · 938 阅读 · 0 评论 -
ExceptionInInitializerError、java.security.NoSuchAlgorithmException: no such algorithm: ECDSA for pro
在集成Tron-java Sdk后运行发现总是异常java.lang.ExceptionInInitializerError......java.security.NoSuchAlgorithmException: no such algorithm: ECDSA for provider BC解决办法:1.在application的onCreate里面加入下面的方法public void setupBouncyCastle() { final Provider provi原创 2021-11-04 17:32:46 · 3265 阅读 · 1 评论 -
WorkManager的基本使用
由于之前的项目都没有相关后台运行的东西,所以对四大组件之一Service很少使用,最近准备深入学习一下。但使用的时候发现都标识为过时了,主要是因为Android高版本的限制和性能问题。推荐的是使用WorkManager来代替。这个还真没使用过。创建一个workerclass DelayWork(context: Context, workerParameters: WorkerParameters) : Worker(context, workerParameters) { overrid.原创 2021-11-01 20:16:33 · 1616 阅读 · 0 评论 -
Android Service 生命周期
普通的Serviceclass NormalService: Service() { override fun onCreate() { logger("onCreate") super.onCreate() } override fun onBind(intent: Intent?): IBinder? { logger("onBind") return null } override fun原创 2021-11-01 19:15:57 · 3306 阅读 · 0 评论 -
Kotlin by 委托
类委托使用场景:当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口。interface Base { fun print()}class BaseImpl(val x: Int): Base { override fun print() { println("BaseImpl:$x") }}class BaseImpl2(val x: Int): Bas原创 2021-10-16 09:34:52 · 150 阅读 · 0 评论 -
静态代理和动态代理
静态代理abstract class BaseClass { abstract fun write()}class StaticClass: BaseClass() { override fun write() { println("StaticClass") }}class RealClass: BaseClass() { var baseClass: BaseClass? = null override fun write() {原创 2021-10-16 09:33:31 · 98 阅读 · 0 评论 -
责任链模式
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。主要解决:职责链上的处理者负责处理原创 2021-10-15 19:58:55 · 87 阅读 · 0 评论 -
Retrofit 基本流程分析
retrofit 是基于okhttp,使用动态代理来实现的。动态代理动态代理在retrofit中其实就是在运行期间去创建interface实例的。我们在使用时都会创建一个interface类,里面再添加一些接口方法。public <T> T create(final Class<T> service) { return (T) Proxy.newProxyInstance( service.getClassLoader()原创 2021-10-11 20:06:46 · 637 阅读 · 0 评论 -
Android 引入so库失败的问题
异常:dlopen failed: library "***.so" not found首先加入对应abi的so文件检查abiFilters中是否和加入so的文件夹对应在android {…} 中加入ndk { abiFilters 'armeabi-v7a','arm64-v8a'}一般这个就能满足大部分的手机了。在在android {…} 中加入sourceSets { main { jni.srcDirs = []原创 2021-09-29 15:56:00 · 577 阅读 · 0 评论 -
Glide-如何感知生命周期的
Gilde的基本使用Glide.with(this).load(imageSrc).into(imageView)这个this可以是多种类型ContextActivityFragmentFragmentActivityView传入它们的类型不同处理方式却大致相同,除了传入的Application都是通过获取FragmentManager来创建一个Fragment以fragment为例获取fragmentManagerFragmentManager fm = fragment原创 2021-09-24 19:58:06 · 334 阅读 · 0 评论 -
Activity 和 Fragment中的Context
ActivitygetBaseContext 这个函数的默认返回类型就是当前的Activity。在启动流程的ActivityThread.class--performLaunchActivity()中appContext.setOuterContext(activity); activity.attach(appContext, this, getInstrumentation(), r.token, r.ident,原创 2021-09-22 19:31:08 · 1020 阅读 · 0 评论 -
jetPack-ViewModel 原理分析
现在viewmodel的实现在androidX前后有两个版本,实现方式有着不小的差异AndroidX前 viewmodel使用方法ViewModelProviders.of(activity/fragment).get(MyViewModel::class.java)ViewModelProviders @MainThread public static ViewModelProvider of(@NonNull Fragment fragment, @Nullable Facto原创 2021-09-10 10:04:44 · 213 阅读 · 0 评论 -
Dialog创建依赖的Context对象必须是Activity吗?
很明显这个问题不是肯定的,是可以为其他的Context的。不然传参就定为了activity了。先看下不传如activity基本的使用。一般用作悬浮窗。在AndroidManifest.xml 里面添加权限<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>检测在应用上层展示的权限是否开启fun checkOverlayPermission(context: Context): Boolean原创 2021-09-06 18:43:45 · 521 阅读 · 0 评论 -
关闭某个activity之前的所有activity
fun jumpToMain(context: Context) { val intent = Intent(context, MainActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK context.startActivity(intent) }原创 2021-09-03 18:57:12 · 174 阅读 · 0 评论 -
JetPack-LiveData 原理分析
LiveData 是一个可以在给定生命周期内观察到的数据持有者类。 这意味着Observer可以与LifecycleOwner成对添加,并且仅当配对的 LifecycleOwner 处于活动状态时,才会通知此观察者有关包装数据的修改。LifecycleOwner 被认为是活动的,如果它的状态是Lifecycle.State.STARTED或Lifecycle.State.RESUMED 。通过observeForever(Observer)添加的observeForever(Observer).原创 2021-09-03 14:57:32 · 148 阅读 · 0 评论 -
JetPack-Lifecycle 原理分析
本文是基于api30 的源码进行分析Lifecycle 的作用对activity和fragment的生命周期进行统一的管理和监听使用场景如果一个业务需要依赖生命周期的控制,你可以重写生命周期方法写到activity或者fragment中,但这样耦合太严重。业务多的话代码会很不优雅。耦合严重。比如mvp模式在页面destory时需要取消一些操作。所以lifecycle的主要目的就是解耦使用方法lifecycle.addObserver(object : LifecycleEventObser.原创 2021-09-02 18:20:19 · 144 阅读 · 0 评论 -
Android 流式布局的实现方式
这里说的流式布局是指view相互跟随,并且可以自动换行的操作。常见的用例为:搜索记录、标签选择等。使用ConstraintLayout + Flow实现 <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/cl_1" android:layout_width="wrap_content" app:layout_constraintStart_toStart.原创 2021-09-01 10:29:16 · 429 阅读 · 0 评论 -
Android 监听Application的生命周期
在application中加入生命周期的监听init { ProcessLifecycleOwner.get().lifecycle.addObserver(object : LifecycleEventObserver { override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) { when(event) {原创 2021-08-31 12:05:41 · 1044 阅读 · 0 评论 -
Android 不重启切换语言
实现多语言的方式1.新建一个values-en文件夹,把values文件夹里面的strings.xml复制过来,把里面的中文替换成英文2.在一个项目中通常会有一个BaseActivity在onCreate中进行语言切换的操作private fun setLanguage() { // 这里在本地存储了语言的设置 val isEnglish = MMKVUtil.getBoolean(MkvConstants.LANGUAGE_TYPE, false)原创 2021-08-30 19:22:46 · 1386 阅读 · 0 评论 -
viewpager2+tablayout+fragment的使用
布局同之前的viewpage一样设置就好<com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content"/> <androidx.viewpager2.widget.ViewPager2 an原创 2021-08-29 21:36:58 · 1100 阅读 · 0 评论 -
Android MaterialToolBar 的使用
这里主要使用的是Material 的MaterialToolbar,首先把App主题设置为NoActionBar创建Menu在res下创建menu文件夹,在文件夹里面创建toolbar_menu.xml文件<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.andro.原创 2021-08-25 15:21:44 · 2841 阅读 · 0 评论 -
自定义GridItemDecoration边框
/** * @author: hsw * @date: 2021/8/23 * @desc: */class GridDividerDecoration constructor( @Px dividerSize: Float, @ColorInt colorInt: Int, private val spanCount: Int) : RecyclerView.ItemDecoration() { private val dividerPaint: Paint =原创 2021-08-24 15:49:49 · 242 阅读 · 0 评论 -
android开发kotlin项目Proguard混淆配置
在Android kotlin 项目中开启混淆后出现了INT for value: v24(2) by constraint: OBJECT一直修改配置,总是不对,找不到原因。最后更改了配置解决了。-flattenpackagehierarchy-allowaccessmodification-keepattributes Exceptions,InnerClasses,Signature,SourceFile,LineNumberTable,-dontskipnonpubliclibraryc原创 2021-08-23 10:37:26 · 2099 阅读 · 0 评论 -
jetpack系列-Room的使用和升级
创建添加Entity@Entity(tableName = "table_user")data class UserEntity( @PrimaryKey(autoGenerate = true) val id: Long? = null, @ColumnInfo(name = "user_name", defaultValue = "new_user") var userName: String? = null, val password: String?原创 2021-08-20 14:32:55 · 248 阅读 · 0 评论 -
android studio 4.0.1 cpp文件不支持的问题
升级到4.1版本即可解决原创 2020-10-14 18:07:32 · 380 阅读 · 0 评论 -
解决android 合并清单列表后某个权限没有了
最近接入了一个第三方sdk,却突然发现不申请READ_PHONE_STATE 权限了。打开第三方aar中的AndroidManifest文件看到<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />看到一个remove初步猜测是这个原因。查了一下文档合并多个清单文件发现就是这个原因,但是在三方aar文件又不好去掉,文档里也.原创 2020-10-13 10:35:18 · 771 阅读 · 3 评论 -
已解决:Cause: unable to find valid certification path to requested target
遇到Cause: unable to find valid certification path to requested target网上大部分的方法就是重启、重装、换网、下载证书。嫌麻烦并没有用上面的方法–耗时间(懒)。在做上面的操作之前,先看看自己的抓包工具有没有开启。我当时正在抓包https,所以造成了证书不正确的情况。...原创 2020-09-22 17:49:19 · 4536 阅读 · 6 评论 -
Android 集成阿里云日志服务报错 NoClassDefFoundError
NoClassDefFoundError 的详细信息为:Failed resolution of: Lcom/aliyun/sls/android/sdk/DaoMaster$DevOpenHelper;这个错误的原因是没有集成greenDao添加implementation 'org.greenrobot:greendao:3.2.2'还有fastJson也是不可缺少的implementation 'com.alibaba:fastjson:1.2.35'...原创 2020-09-11 11:55:07 · 434 阅读 · 0 评论 -
仿马蜂窝TabLayout 波纹滑动菜单导航栏
先看一下马蜂窝的样式我刚看到觉得下面的样式好神奇,自己就像动手做一做。由于数学方面我不是很精通,我的实现方式没有复杂的公式计算,而是通过绘制+覆盖的形式。这里借用了原创 2020-07-20 19:46:28 · 661 阅读 · 0 评论 -
自定义ViewPager和RecyclerView指示器 Indicator
现在好多App首页都会有这样的条目这种的实现方式要么是viewpager翻页滚动,要么就是recyclerView持续滚动。下面的指示器系统的太丑 ,所以就自定义了一个。下面是demo简单的效果图:ViewPagerIndicator因为嫌麻烦这里的指示器没有用Canvas进行绘制,用了布局文件代替:指示器布局文件 view_indicator.xml<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:an原创 2020-07-14 18:12:39 · 1284 阅读 · 0 评论 -
CoordinatorLayout+AppBarLayout,触碰AppBarLayout中的一些view时不能滑动
问题:CoordinatorLayout+AppBarLayout,触碰AppBarLayout中的一些view时不能滑动解决方式:自定义一个AppBarLayoutBehavior继承自AppBarLayout.Behavior在constructor中调用setDragCallback方法,并实现DragCallback 返回值为truepublic AppBarLayoutBehavior() { setDragCallback(new DragCallback() {.原创 2020-07-13 19:49:29 · 945 阅读 · 0 评论 -
Could not inflate Behavior subclass
为了处理CoordinatorLayout + AppBarLayout + ViewPager滑动出现回弹和卡顿的现象,自定义的一个AppBarLayoutBehavior,但在运行过程中会出现java.lang.RuntimeException: Could not inflate Behavior subclass刚开始的布局如下:<android.support.design.widget.CoordinatorLayout android:layout_wid.原创 2020-07-13 14:22:36 · 4012 阅读 · 1 评论 -
Android 四种启动模式实践
standard–standard连续启动两个standard模式的activity这是默认的启动模式,每次启动都会创建新的实例,生命周期也是从头开始singleTop–singleTop连续启动两个singleTop模式的activity当堆栈中已经存在实例的话 直接不再创建,通过onNewIntent 传递数据。生命周期会经历 onPause - onNewIntent - ResumesingleTask–singleTask连续启动两个singleTask模式的activity原创 2020-06-23 15:47:56 · 279 阅读 · 0 评论 -
BottomSheetDialog 增加关闭动画
bottomSheetDialog.setDismissWithAnimation(true);然后再dismiss就有动画了原创 2020-05-14 09:42:11 · 1788 阅读 · 0 评论 -
Android 垂直滑动解锁,水平滑动解锁
直接代码,讨厌要积分的,好使给个star谢谢https://github.com/MyUserNameHSW/SlideLockView.git原创 2020-03-17 15:43:30 · 260 阅读 · 1 评论