自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Restless Breeze

Android小白奋斗之路

  • 博客(87)
  • 资源 (2)
  • 收藏
  • 关注

原创 ProGuard混淆及R8优化

保留Parcelable序列化的类不被混淆# 保留Serializable序列化的类不被混淆使用GSON、fastjson等框架解析服务端数据时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象;这一点也是开发中经常忽略的问题# 保留自定义控件(继承自View)不被混淆*** get*();ok,到这里,基本proGuard的混淆规则就大致结束了。不用死记规则,但得知道有这么个东西,打包release包时,能定位出混淆所带来的问题就行了。

2023-06-23 20:04:01 1998

原创 Getx系列之Dialog

针对Dialog的封装,如果封装的widget需要传入context,那就不算好的封装成品。在原生开发中,就很厌烦传入context,有些未封装完美的工具类t,比如oast、dialog等需要传入context。而针对flutter应用开发,Getx就封装了一个不需要传入context对象且可自定义的dialog。

2022-09-04 12:35:58 4471 1

原创 startActivityForResult废弃了,用Activity Result API吧

在MainActivity里通过点击一个按钮,往Bundle里添加数据,然后放到intent里,通过startActivityForResult向SecondActivity传递数据,并且重写了onActivityResult()方法去解析SecondActivity返回来的数据。SecondActivity就稍微简单点了,先获取到MainActivity传递过来的数据,然后再点击一个按钮,发送新的数据返回给MainActivity。废弃了,自然有替代品。所以才发现过时的,如果版本低了,我还蒙在鼓里。

2022-09-02 22:37:22 5201 1

转载 api与implementation的区别

从上面的例子可以看出,在多module中,implementation确实可以起到隐藏依赖的作用,网上很多的文章都只讲到了这点,那么这样做的目的是什么呢?不过,在远程依赖模式下,依赖的一个模块如果版本发生变化,implemention与api的构建速度谁快谁慢还需要进一步研究。三、现在在回过头来看一下依赖传递的问题,之前验证了使用implemention,app不能拿到MyClass3,这是在本地依赖的情况下,而现在的模块化开发多采用远程依赖的模式进行合作。那么如果采用maven远程依赖呢?

2022-08-20 20:40:34 4959

原创 “Controller“ not found. You need to call “Get.put(Controller())“ or “Get..lazyPut(()=>Controller())

Unhandled Exception: "XXXController" not found. You need to call "Get.put(XXXController())" or "Get.lazyPut(()=>XXXController())"

2022-08-19 21:28:03 3399

原创 Java破坏单例模式的方式及原理

单例的目的:仅允许程序中存在有且仅有一个实例单例的好处:1、对于频繁使用的对象,可以省略创建对象所需的时间。2、减少了new对象的操作次数,降低了系统内存的使用频率,减轻了GC的压力,缩短了DC的停顿时间。......

2022-08-17 22:09:39 769

原创 LiveData的postValue丢值?setValue也丢值?

postValue方法内部其实是将值得回调逻辑放到了Runnable中,再post给Handler,利用Handler在主线程中更新,因此从postValue到执行Runnable,中间是存在时间差的,同时也说明 postValue是可以在子线程中发送数据的,在执行Runnable之前,因为是连续调用的postValue,只有在页面活跃状态下才可以分发值,当可以点击按钮时候,当前Activity 的生命周期已经走过了 OnStart、onResume,第四个是因为 LiveData 的观察生命周期的特性,.

2022-08-16 22:34:02 2012 2

原创 c++ 结构体

整形、长整形、字符型以及浮点型等这些数据类型指南记录单一的数据,而这些数据只能被称为基础数据类型。如果需要定义某种类型,同时包含以上几种的基本数据类型。比如一个人同时含有身高、体重以及年龄的属性。而结构体就是将这些变量类型包含在一起,大大减少程序代码的离散性,使程序代码阅读更加符合逻辑。struct 结构体类型名称{成员类型 成员名;...成员类型 成员名;};struct就是定义结构体的关键字。结构体类型名称就是一种标识符,该标识符表示一个新的变量。结构体是以大括号括起来且以分号结尾。...

2022-08-14 18:11:06 7469 3

原创 Getx在Controller里添加TabController的处理

其实处理方式也很简单,getx提供了GetSingleTickerProviderStateMixin去处理tabBarView的tab点击监听事件的。其实处理方法和在StatefulWidget里的state里一样,无非一个是在widget里,一个在Controller里。二、假如我又需要自己控制TabController呢,DefaultTabController不能监听到tab的点击处理事件,咋办?正好因为项目中遇到这个问题,网上搜了下,不少同学也遇到了。有同学就提出此疑问,...

2022-08-11 23:00:17 3733 3

原创 c++函数

函数的定义的一般形式如下返回值类型 函数名(参数列表){函数体return 返回值;}举个例子:如果一个函数没有返回值,那么它的返回值类型可以用void来代替,return语句则不需要再添加了。}注意点:1、参数列表可以为空,这样就定义了一个无参数的函数。2、函数后面的大括号表示函数体,在函数体内可以进行变量的声明以及语句的添加等。.........

2022-08-07 19:19:32 1981

转载 Kotlin系列之let、with、run、apply、also函数的使用

文章转载来自于阿里大佬之文章很好,恐大佬怒删,特此转载备份,客官可直接移步去大佬的文章细看。简述:相比Java, Kotlin提供了不少高级语法特性。对于一个Kotlin的初学者来说经常会写出一些不够优雅的代码。在Kotlin中的源码标准库(Standard.kt)中提供了一些Kotlin扩展的内置函数可以优化kotlin的编码。Standard.kt是Kotlin库的一部分,它定义了一些基本函数。这个源代码文件虽然一共不到50行代码,但是这些函数功能都非常强大。......

2022-08-07 10:28:11 525

原创 C++命名空间

虽然两个命名空间中定义的变量都是一样的,但因为在不同的命名空间中,所以避免了标识符的冲突,保证了标识符的唯一性。命名空间可以定义在其他的命名空间中,在这种情况下,仅仅通过使用外部的命名空间作为前缀,程序便可以引用在命名空间之外定义的其他标识符。在定义命名空间时,通常在头文件中声明命名空间中的函数,在源文件中定义命名空间中的杉树实现,将程序的声明和实现分开。在源文件定义函数时,注意要使用命名空间名作为前缀,表明实现的是命名空间中定义的函数,否则将是定义一个全局的函数。在引用空间中的成员是可以直接使用的。...

2022-07-31 08:00:00 369

原创 c++ goto语句

这是一种不提倡的做法,它会使得程序的执行循序变得混乱,cpu需要不停地进行跳转,效率比较低,而且goto语句任何程序可以修改,程序中如果出现多处相同的标签会使得程序逻辑变得复杂,因此,在开发中时慎用goto语句。如果程序中出现上述情况,可以在标签后面添加一个可执行的语句就行了,以解决编译错误,比如添加一行打印输出语句。如果添加goto语句后,改变程序的执行顺序,例如运行完cout...

2022-07-30 22:41:16 10991

原创 swift基础学习笔记

当你声明常量或者变量的时候可以加上类型标注(type annotation),说明常量或者变量中要存储的值的类型。如果要添加类型标注,需要在常量或者变量名后面加上一个冒号和空格,然后加上类型名称1.2 自动类型推断 swift 可以自动类型推断 ,当你要处理不同类型的值时,类型检查可以帮你避免错误。然而,这并不是说你每次声明常量和变量的时候都需要显式指定类型。如果你没有显式指定类型,Swift 会使用类型推断(type inference)来选择合适的类型。1.3 类型安全

2022-06-24 22:42:03 1210 1

原创 flutter与android原生通信

刚接触flutter的时候,以为flutter是一个全新开发app的语言,独立于Android原生之外的操作,入坑之后发现不是的。因为Flutter不能完成所有Native的功能,比如不同平台的底层服务如电量变化、网络连接变化以及最近项目中使用的直接拨号功能以及地图功能都无法用flutter实现其功能,因此需要借助Native层的接口来实现flutter的开发,所以Flutter提供了一套Platform Channel的机制,来满足Flutter与Native通信的需求。图中可以看到,Flutter是Cl

2022-06-03 22:06:20 5215 5

原创 flutter-剪裁(Clip)

Flutter中提供了一些剪裁函数,用于对组件进行剪裁。 剪裁Widget 默认行为 ClipOval 子组件为正方形时剪裁成内贴圆形;为矩形时,剪裁成内贴椭圆 ClipRRect 将子组件剪裁为圆角矩形 ClipRect 默认剪裁掉子组件布局空间之外的绘制内容(溢出部分剪裁) ClipPath 按照自定义的路

2022-03-17 21:11:56 5270

原创 flutter-Button

ElevatedButton即"漂浮"按钮,它默认带有阴影和灰色背景。按下后,阴影会变大圆角设置 ElevatedButton( style: ButtonStyle( shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(20)))), onPressed: (() {}), child: Text(

2022-03-17 17:45:46 4499

原创 flutter-拨打电话功能

使用插件:url_launcher添加插件命令行添加:flutter pub add url_launcher这会自动在pubspec.yaml添加 url_launcher: ^6.0.20建议直接命令行添加,这样就不用关系版本是不是写对了,或者配置文件里配置错误什么的问题出现导包在队员要使用该插件功能的里面导入包,如下import 'package:url_launcher/url_launcher.dart';使用tel:<phone numbe

2022-03-16 20:39:51 7604 1

原创 Dart学习笔记(8): 语法糖

??=如果左边为空,则进行右边的赋值运算,如果左边不等于null,则返回当前对象 String param1 = "hello"; String? param2 = null;// param1不为空,直接返回param1 print(param1 ??= "world"); 打印hello // param2为空,然后进行右边的赋值运算 把"world"重新赋值给了param2 print(param2 ??= "world"); //打印world ??A??B

2022-03-08 22:57:35 357

原创 Dart学习笔记(7): future

Dart代码在单线程中执行代码在运行线程中阻塞的话,会使程序冻结Future对象(futures)表示异步操作的结果,进程或者IO会延迟完成在async函数中使用await来挂起执行,直到future完成为止(或者使用then)在async函数中使用try-catch来捕获异常(或者使用catchError())Future 的常用函数Future.delayed()=>延迟执行一个延时任务。Future.then()=>任务执行完成会进入这里,能够获得返回的执行.

2022-03-06 15:22:16 1251

原创 Dart学习笔记(6): 泛型

1.外层与内层滑动方向不一致,外层ViewGroup是可以横向滑动的,内层View是可以竖向滑动的(类似ViewPager,每个页面里面是ListView)2.外层与内层滑动方向一致,外层ViewGroup是可以竖向滑动的,内层View同样也是竖向滑动的(类似ScrollView包裹ListView)...

2022-03-05 18:18:11 792

原创 Dart学习笔记 (5):类

类:Dart 是支持基于 mixin 继承机制的面向对象语言,所有对象都是一个类的实例,而除了 Null 以外的所有的类都继承自 Object 类使用类的成员对象的 成员 由函数和数据(即 方法 和 实例变量)组成。方法的 调用 要通过对象来完成,这种方式可以访问对象的函数和数据。使用 . 来访问对象的实例变量或方法class Person { String? name; String? age; void getName() {}}main() { var

2022-03-04 22:14:38 1807

原创 Dart学习笔记 (4):异常

Dart中表示异常的类有两个,分别是Exception和Error。Exception是由VM或者dart code中抛出的。Exception主要用来表示用户程序编写过程中产生的异常,是可以定位到的可以解决的异常。通常来说Exception中包含了足够的信息来方便用户来定位异常点。所以Exception通常是需要被catch的。但是和java不同的是,dart中所有的异常都是unchecked 异常,也就是说dart中的异常并不强制要求被捕获,是否捕获异常是由程序员自行决定的。dart中也有很多E

2022-03-04 21:44:47 2145

原创 Dart学习笔记(3):函数

函数Dart 是一种真正面向对象的语言,所以即便函数也是对象并且类型为 Function,这意味着函数可以被赋值给变量或者作为其它函数的参数。定义一个函数比如: String getName(String name){ return "my name is${name} "; }返回值类型可以省略: getName(String name){ return "my name is${name} "; }如果函数体内只包含一个表达式,你可以使用简写语法:getName

2022-03-03 23:04:55 453

原创 Okhttp 双任务队列机制

为了完成调度和复用,定义了两个队列分别用做等待队列(readyAsyncCalls)和执行任务(runningAsyncCalls)的队列。这两个队列都是Dispatcher成员变量。Dispatcher是一个控制执行,控制全部Call的分发和任务的调度、通讯、清理等操作。/** Ready async calls in the order they'll be run. */private final Deque<AsyncCall> readyAsyncCalls = new ...

2022-01-19 17:14:06 2327

原创 MMKV——基于 mmap 的高性能通用 key-value 组件

MMKV 原理 内存准备 通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。 数据组织 数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。 写入优化 考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。 空间增长 使用 append 实现增量更新带来

2020-09-22 15:46:26 413

转载 post和get区别

HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。GET和POST能做的事情是一样一样的。...

2020-09-22 11:24:20 16781 12

原创 java基础

java继承-java继承从“我爸是李刚”讲起 java多态-深入理解java多态没有烤山药的存在,java就不香了吗? java泛型-泛型 java static-深入理解static关键字 静态代码块- java异常-死了都要try,不淋漓尽致地catch我不痛快! 内部类:java内部类有什么作用? 匿名内部类:程序员你真的理解匿名内部类吗? 反射机制:程序员你真的理解反射机制吗? 堆和栈的概念和区别 Java虚拟机(JVM) ...

2020-08-04 21:56:05 192

原创 java中的==和equals的区别?

equals本身和 == 没有区别,对于基本数据都是比较值,对于引用类型,则比较的是所指向的对象的地址!从java语言本质上来讲,"=="属于JAVA语言的运算符,而equals则是根类Object的一个方法。Object类的equals()与 “ == ”没有任何区别!源码:equals底层其实就是“ == ”,也就是说,原生的equals()方法本身与 “ == ”没有任何区别!唯一的区别则是基本类型没有继承Object类,所以基本类型没有equals()方法,也就是说基本类型只

2020-08-04 16:56:59 398

转载 Android线程池ThreadPool浅析

1.传统开启线程方式:new Thread(new Runnable() { @Overridepublic void run() {。。。。。。}}).start();new Thread的弊端如下:a. 每次new Thread新建对象性能差。b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,线程过多,导致各个线程竞争抢夺CPU执行权,线程的频繁切换导致效率的降低,及可能占用过多系统资源导致死机或oom。c. 缺乏更多功能,如定时执行、定期执行、线程中断。2.使

2020-08-01 13:36:00 459

原创 Bitmap的高效加载策略

一、为什么Bitmap需要高效加载?现在的高清大图,动辄就要好几M,而Android对单个应用所施加的内存限制,只有小几十M,如16M,这导致加载Bitmap的时候很容易出现内存溢出。如下图所示,便是在开发中经常遇到的异常信息:java.lang.OutofMemoryError:bitmap size exceeds VM budget为了解决这个问题,就出现了Bitmap的高效加载策略。其实核心思想很简单。假设通过ImageView来显示图片,很多时候ImageView并没有原始图片的尺

2020-07-31 10:34:56 259

原创 进制之间的换算

进制也就是进制位,对于接触过电脑的人来说应该都不陌生,我们常用的进制包括:二进制、八进制、十进制与十六进制,它们之间区别在于数运算时是逢几进一位。比如二进制是逢2进一位,十进制也就是我们常用的0-9是逢10进一位。十进制转二进制方法为:十进制数除2取余法,即十进制数除2,余数为权位上的数,得到的商值继续除2,依此步骤继续向下运算直到商为0为止。(具体用法如下图)二进制转十进制方法为:把二进制数按权展开、相加即得十进制数。(具体用法如下图)二进制与八进制之间的转换.

2020-07-23 21:58:31 3924

原创 Android apk反编译java代码

工具下载链接:https://download.csdn.net/download/csj731742019/12655396第一步:首先将apk文件后缀改为zip并解压,得到其中的classes.dex,它就是java文件编译再通过dx工具打包而成的,将classes.dex复制到dex2jar.bat所在目录下。第二步:在命令行下定位到d2j-dex2jar.bat所在目录,运行d2j-dex2jar.bat classes.dex生成classes_dex2jar.j...

2020-07-23 17:12:02 377

原创 CrashHandler全局异常捕获

应用在日常的开发中,我们经常需要去Logcat测试我们的App,但由于很多原因,Android Monitor会闪屏或者Crash信息丢失。 这个时候就需要一个CrashHandler来将Crash写入到本地方便我们随时随地查看安卓已经帮我们想好了解决问题的接口(UncaughtExceptionHandler)。从名称上就知道这是用来处理没有捕捉到的野生Exception的。平时我们try catch的Exception的那就叫捕捉到的。看一下UncaughtExceptionHandler的源码:

2020-07-23 16:14:04 2259

原创 Android 快速定位ANR问题

定义:在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作“应用程序无响应”(ANR:Application Not Responding)对话框。用户可以选择“等待”而让程序继续运行,也可以选择“强制关闭”。因此,在程序里对响应性能的设计很重要,这样,系统不会显示ANR给用户。默认情况下,在Android中Activity的最长执行时间是5秒(主要类型),BroadcastReceiver的最长执行时间的则是10秒,ServiceTimeout的最长执

2020-07-23 10:39:46 764

转载 HashMap为啥初始化大小是16

HashMap的默认初始化长度是多少?static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16在JDK1.8的 235 行有1<<4就是16,为啥用位运算呢?直接写16不好么?这里主要是位运算的性能好,为啥位运算性能就好,那是因为位运算人家直接操作内存,不需要进行进制转换,要知道计算机可是以二进制的形式做数据存储啊,这里使用了位运算,为啥不直接16嘞?这里主要是位运算的性能好,为啥位运算性能就好,那是因

2020-07-21 14:59:40 7701 7

原创 浅析哈希表

哈希表定义:散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。(摘自百度百科)散列函数:是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。常用Hash函数有:1.直接寻址

2020-07-21 10:04:20 425

原创 AsyncTask的简单使用

功能:实现工作线程 & 主线程(UI线程)之间的通信,即:将工作线程的执行结果传递给主线程,从而在主线程中执行相关的UI操作。在使用AsyncTask时,我们无需关注Thread和Handler,AsyncTask内部会对其进行管理,这样我们就只需要关注于我们的业务逻辑即可。属于抽象类,即使用时需 实现子类public abstract class AsyncTask<Params, Progress, Result> {}参数介绍Params:开始异步任务执行时.

2020-07-19 21:13:13 925

原创 RxJava - combineLatest操作符

combineLatest()作用于最近发射的数据项,在其中一个Observable发射数据项后,组合所有Observable所发射的最后一个数据项(前提是所有的Observable都至少发射过一个数据项),如下图所示;其原理即:如果Observable1发射了1,接着Observable2发射了A,combineLatest()将会处理1和A,组合成1A;而Observable1发射了2,此时Observable2只发射了A,所以combineLatest()将处理2和A,组合成2A;待Obser

2020-07-15 15:57:08 428

原创 Rxjava-线程控制 Scheduler

在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。想要在RxJava中引入多线程的功能,可以使用一些操作符使得RxJava在指定的线程上运行,即实现线程的切换功能。比如说一些耗时的操作,如我们看电影,一个线程在后台下载数据,然后播放视频在当前的线程,这样就可以给我们更好的观影体验。在RxJava 中,Scheduler——调度器,相当于线程控制器,RxJava 通过它来指定每一段代码..

2020-07-06 09:35:01 533

反编译工具_26861.zip

Apk反编译得到Java源代码将apk文件后缀改为zip并解压,得到其中的classes.dex,它就是java文件编译再通过dx工具打包而成的,将classes.dex复制到dex2jar.bat所在目录文件夹

2020-07-23

Android调用手机系统自带录音功能实现语音录制与播放

Android调用手机系统自带录音功能实现语音录制与播放

2016-12-20

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除