- 博客(44)
- 资源 (5)
- 收藏
- 关注
原创 App埋点
不能忘记埋点的初衷,要有目的的去埋点。其中各个渠道的下载量,用户留存情况是很重要的,还有首页等重要界面按钮,banner等的点击量,直接关系到我是否有必要把它放在首页。统计某些页面的访问量有助于我们分析,这个页面使用频率不高是不是可以放在更边角的地方,或者说是不是设计有问题需要改进。比如有一个流程操作,他是分好几个步骤进行的,我们可以统计用户的每步操作,这样我们就能建立一个漏斗模型,观察到在整个流程中用户在每个步骤的留存情况,借此来改进这个步骤操作。下面这些是比较常见的需要统计的方向:用户数据:新增
2022-01-26 15:36:28
562
原创 加载插件Apk中的类
方法1:使用类加载器将插件Apk打包放到手机中,这里路径是PluginApkPath。然后构建DexClassLoader类加载器加载该Apk,之后可以该类加载器的 loadClass(全类名) 方法来加载apk中的类。之后通过反射来获取他的成员变量和方法。 DexClassLoader pluginClassLoader = new DexClassLoader(PluginApkPath, getDir("my_dir", MODE_PRIVATE).getAbs
2022-01-18 17:08:38
2183
原创 SharedPreferences
SharedPreferences用于Android本地存储,使用较简单。SharedPreferences本身是一个接口,它的实现类是SharedPreferencesImpl,通过源码可以发现他的put和get方法都有synchronized锁,因此它是线程安全的。SharedPreferences基本使用存值 SharedPreferences sp = context.getSharedPreferences("sp_storage", Context.MODE_PRIV
2022-01-11 16:42:40
1996
原创 EventBus
EventBus通过发布/订阅模式来实现组件间的通信。他相比与广播更加轻量,更适合应用内的通信,广播更适合与Android系统交互以及跨进程的通信。使用在app下的build.gradle下引入依赖implementation 'org.greenrobot:eventbus:3.1.1'事件传递对象public class Person { private String name; private int age; public Person(Stri
2022-01-08 13:22:00
1194
原创 手写路由框架
我们平时Activity的跳转用的是下面的代码 Intent intent = new Intent(activity, SecondActivity.class); activity.startActivity(intent);但是在组件化中各个module都是可插拔的,可能上面的SecondActivity所在的module没有被依赖,那么上面的代码就会报红。为了解决这个问题,我们可以用一个映射表来存储路径key和对应的Activity,这么一来就不会报红,我们可
2022-01-07 16:19:04
651
原创 Android内置存储和sdcard存储(路径)详解
内置存储(external storage,/data/data下)context.getCacheDir().getPath() //路径为data/user/0/{packageName}/cache,不需要权限 context.getFilesDir().getPath() //路径为data/user/0/{packageName}/files,不需要权限 context.getDir("myDir", MODE_PRIVATE).getPath() //路径为data/user/0/{..
2021-12-30 17:24:50
9245
2
原创 插件化解析
什么是插件化将App功能拆分成多个模块,每个模块都是一个apk,最终打包成宿主apk和多个插件apk,插件apk放到云端通过接口动态下发到宿主apk,实现功能集成。插件化的优势宿主apk和插件是分开编译的,是两个apk,更利于多人开发。 插件模块功能的迭代更新和bug修复可以通过服务端接口动态下发,不需要重新下载安装整个apk,更加灵活方便 主apk的各个功能模块,用户可以按需下载,可以减小主apk的包体积 可以解决65535问题插件化的原理通过一个宿主Activity成为插件apk
2021-12-30 15:14:43
1452
原创 ThreadLocal解析
作用为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。原理ThreadLocal内部维护了一个ThreadLocalMap,这个map不是实现的Map接口,但是也是存储键值对,底层采用数组实现,处理hash冲突通过线性探测法(就是通过hash运算获得的数组下标如果冲突则往i+1放,如果有了再+1,如果要越界则从0开始再以此判断)。早先的ThreadLocal是在ThreadLocal下维护TheadLocalMap,然后map中存的key是Thead,value是线程中需要用到的
2021-12-23 14:23:00
483
原创 抖音视频发布,字节小程序的坑
功能描述:首先为商家做好了礼品领取页的二维码,用户扫码可进入网页端,用户答应抖音发布视频授权之后可以领取礼品,领取后会自动在用户抖音上发布一条推广视频,推广视频上带有商家小程序的链接,可供观看视频的人点击进入领取商品再分享,实现裂变。这里就涉及到了网页端获取抖音授权和小程序端获取抖音授权的两条路线。因为我们需要同时在网页端和字节小程序端的使用,所以我这边使用的是uni-app来编写以供多端使用。首先是二维码根据抖音开发平台(抖音开放平台)介绍,可以拼接如下的url生成二维码供用户扫码。注
2021-12-07 16:33:19
3028
1
原创 Apk打包、安装、签名
1.aapt工具会在我们编码时打包res资源文件,生成R.java、resources.arsc和res文件。2.aidl工具解析接口定义文件然后生成相应的Java代码接口供程序使用。如果项目没有用到aidl则不会执行这一步。3.Java Compiler阶段,将R.java,aidl生成的java文件,以及我们程序的java代码,通过Java编译器(javac)编译成.class文件。4.通过dx工具,将所有.class文件处理成.dex文件。5.通过apkbuilder工具将resour
2021-12-02 23:40:38
1079
原创 LayoutInflater
我们一般用下面这种方式来用xml构建View。View view = LayoutInflater.from(context).inflate(resourceId, parent, attachToRoot);resourceId是xml布局文件,parent是父布局,如果parent设置为空,则构建的View将是一个独立的个体,属性无效。如果parent不为空,设置attachToRoot为false,则属性值会依托于root构建,所以此时的xml根布局的属性有效,但是resourceId生成的
2021-11-21 23:49:49
188
原创 Bitmap和图片相关优化
Bitmap优化可做1:像素优化,过大的原图缩小适当尺寸使用 2:内存复用 3:缓存缓存一般有三级缓存:先内存中找,再磁盘中找,最后网络找。Bitmap内存优化,如下可以调整bitmap大小和设计图一致,不失真。并且启用Bitmap复用public class BitmapUtil { public static Bitmap resizeBitmap(Context context, int id, int maxW, int maxH, boolean hasAlpha, Bitm
2021-11-10 00:02:06
735
原创 Android编译提示文件路径过长,Gradle CreateProcess error=206
可以在Project目录下的build.gradle中加入:allprojects { buildDir = "C:/tempapp/${rootProject.name}/${project.name}" ... }}
2021-04-14 15:28:57
262
原创 Node.js环境搭建
下载下载网址:https://nodejs.org/zh-cn/点击下载长期支持版。另外一个属于尝鲜版,不够稳定。我这边下载的是node-v12.14.0-x64.msi,双击开始安装,选择安装路径,一路next安装完毕。安装完成查看:查看是否安装成功node -v 查看 node 版本npm -v 查看 npm 版本如下图所示则安装成功。环境配置若想将...
2021-01-04 09:15:34
134
原创 React
渲染元素<!DOCTYPE html><html><head><meta charset="UTF-8" /><title>Hello React!</title><script src="https://cdn.staticfile.org/react/16.4.0/umd/react.developm...
2020-03-20 17:38:56
160
原创 配置阿里云code的ssh
配置git config --global user.name 您的名字git config --global user.email 您的邮箱地址验证前面做的那些配置git config --global --list接下来配置ssh,在打开git命令终端,输入cat ~/.ssh/id_rsa.pub出现如下提示就说明没有这个文件,需要我们手动创建ssh公钥和私钥...
2020-02-03 10:35:08
1217
原创 Fragment常规使用
创建 MyFragment fragment = new MyFragment(); FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transa...
2019-12-04 09:44:45
127
原创 根据图片获取主题色
Palette引入implementation 'com.android.support:palette-v7:27.1.1'使用Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() { @Override public v...
2019-09-06 11:12:08
990
原创 Android Studio插件
1.Translation中英文翻译插件2.GsonFormatjson转JavaBean3.Android ButterKnife Zelezny配合ButterKnife实现注解4.Android Code Generator根据layout生成Activity,Fragment,Adapter,Menu5.Android Parcelable code gen...
2019-08-27 16:24:53
196
原创 手机抓包
Fiddler抓包配置1.打开Tools下的Telerik Fiddler Options..2.Connections配置如下3.https配置如下4.如果需要抓Https,则还需要安装Https证书获取Fiddler所在电脑的IP地址,通过cmd输入命令ipconfig打开手机浏览器,访问http://192.168.8.8:8888,点击"Fiddler ce...
2019-08-27 15:07:05
561
原创 安卓6.0权限申请
1.原生申请权限案例:<uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission androi...
2019-08-22 14:01:37
728
1
原创 App写入渠道号
walle git地址:https://github.com/Meituan-Dianping/walle注意打包使用V2签名,加固如梆梆,360的签名工具如果还是使用v1会使用不了walle。在项目下的build.gradle中添加:buildscript { dependencies { classpath 'com.meituan.android.w...
2019-06-14 10:20:39
1231
原创 instanceof, isinstance,isAssignableFrom说明
instanceof:检测左边对象是不是右边类或接口的实例化。如果左边的是null则直接返回false。obj instanceof 类例子:String s = new String("aaa");if(s instanceof String){ System.out.println("true");}输出trueisInstance:Class类的方法,判断ob...
2019-05-31 14:10:27
169
原创 状态模式
当行为取决于状态时可以使用状态模式,比如和登录相关的进入收藏,购物车,发起评论之类的按钮。可用于解决if-else和switch逻辑。状态模式更偏向于状态引起的一些行为的改变。策略模更偏向于使用不同的算法来实现一个功能。public interface UserState { /** * 购物车 */ public void shoppingCart(...
2019-05-16 15:00:28
143
原创 桥接模式
多维度独立变化,且可扩展。桥接模式相比策略模式,策略模式更注重算法,一种策略一套机制,而桥接模式结构更复杂,可根据场景拼凑不同维度。例如奶茶制作,可分大杯,中杯,小杯,配料可加珍珠,香草波霸... 这场场景可以使用桥接模式。例子:public abstract class Something { public abstract String addSomething();...
2019-05-15 14:05:15
307
原创 策略模式
针对一个问题有多种处理办法时可以使用策略模式。当有很多if-else或者switch时可以考虑设置策略。策略模式和代理模式在应用情景上有点相似,但是代理模式有一个代理类,将对子类的选择封装在其中,对外通过代理类提供服务。而策略模式则是通过动态注入的方式设置合适的策略。策略模式更侧重于策略或是算法的封装隔离,而代理模式更侧重于通过代理类提供代理服务例子:public interface...
2019-05-15 11:47:24
131
原创 适配器模式
将类的接口转为为目标接口。相当于现实中的转接口。下面是一个将TypeC接口转化为Usb接口的例子。public interface Usb { void isUsb();}public class UsbImpl implements Usb{ @Override public void isUsb() { System.out.prin...
2019-05-15 11:29:16
123
原创 抽象工厂模式
抽象工厂是建立在工厂模式的基础上。一个总工厂下有多个工厂,每个工厂下又有相应的产品。public interface Person { void work();}public class Man implements Person{ @Override public void work() { System.out.println("男人:耕地...
2019-05-14 17:31:57
100
原创 工厂模式
工厂模式非常适合用来创建对象。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。创建公共接口:public interface Person { void work();}public class Man implements Person{ @Override public void work()...
2019-05-14 17:02:46
125
原创 外观模式
隐藏系统的复杂性,并向客户端提供了一个可以访问系统的接口。把需要对外暴露的方法统一放在外观接口或类里面,隐藏其他的子模块。例子:创建一个接口public interface Person { void work();}public class Man implements Person{ @Override public void work() {...
2019-05-14 16:11:47
223
原创 装饰器模式
向一个现有的对象添加新的功能,同时又不改变其结构。比如一个人,我们可以给他装饰帽子,衣服等,又不影响本身人的特点。例子:public interface Person { void show();}public class Man implements Person{ @Override public void show() { Syst...
2019-05-14 15:52:54
360
原创 代理模式使用
场景:不直接访问某个对象时,可设置一个代理对象来间接访问,为了保证代码的透明度,委托对象与代理对象需要实现相同的接口。静态代理和动态代理;代理类和被代理类都要继承或实现相同的接口或方法;代理类通过被代理类的引用来调用具体的业务逻辑。抽象主题类public abstract class Test{ public Test() { } public abstr...
2019-05-14 10:21:40
128
原创 观察者模式
描述:每当一个对象改变状态,所有依赖于它的对象都会得到通知并自动更新。 (发布和订阅,将观察者和被观察者解耦)观察者:public class TestObserver implements Observer{ private String mStr; public TestObserver(String str) { mStr= str; }...
2019-05-10 17:37:13
160
原创 Builder模式
下面是个多参数构造的例子,也可设置默认值。Builder模式可以对不同顺序和数量的多参数结构进行较好的处理。Builder简单的示例代码:public class Student{ private String name; private int age; private boolean sex; public String getName() {...
2019-05-10 17:10:03
135
原创 单例设计模式
描述:确保某个类只有一个实例供全局调用。推荐使用:1.双重检查锁定模式:Double Check Lock (DCL)模式注意:要用volatile关键字,否则还是会导致创建多个实例public class Singleton { private volatile static Singleton singleton = null; private Singlet...
2019-05-10 14:11:11
141
原创 android数据库调试
查看手机中的数据库:1.首先打开Device File Explore,位置如下。2.在data/data下找到自己的包名下的db文件save到本地。3.可以用db查看工具查看,也可以下载Android Studio插件安装完成后,重启Android Studio则会显示该工具。可以在此处添加之前导出的db文件创建完成后可以调试sql语句。...
2019-04-24 16:55:36
936
原创 ANR
全称:Application for Responding(应用程序无响应)原因:当前的事件没有机会得到处理,例如UI线程正在响应另外一个事件,当前事件由于某种原因被阻塞了。 当前的事件正在处理,但是由于耗时太长没能及时完成ANR定位和分析:可以通过结合Logcat日志和生成的位于手机内部存储的/data/anr/traces.txt文件进行分析和定位。adb shell...
2019-04-02 11:52:47
151
原创 Builder模式
Builder模式自动生成插件,Android Studio中Plugins下搜索InnerBuilder。常用的Builder模式示例如下:public class People { private final String firstName;//必选 private final String secondName;//必选 private final in...
2019-04-02 10:31:34
99
原创 Gradle基本配置
1.共享变量定义一个名为common_config.gradle的文件放在工程根目录下。内容如下:project.ext{ //java语言 javaVersion = 8 javaMaxHeapSize = '4G' //Android编译版本 compileSdkVersion = 27 buildToolsVersion ...
2019-04-02 09:26:35
560
mybatis-generator-core
2018-03-28
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人