- 博客(105)
- 收藏
- 关注
原创 OpenGL ES 3.0管线渲染流程
OpenGL ES 3.0实现了具有可编程着色功能的图形管线,由两个规范组成:- OpenGL ES 3.0 API规范- OpenGL ES 着色语言3.0规范
2022-08-19 16:07:01 893 1
原创 性能优化总结
性能优化方向流畅(启动速度、卡顿)稳定(内存泄漏、崩溃)功耗(耗电、网络)安装包(包体积)一、 流畅 卡顿优化1、 布局优化简单布局使用Java代码代替布局文件Android加载Xml布局文件,并将其转换成View,需要经历XML解析,使用Java代码直接创建View可以省去这一过程使用标签:复用布局标签: 配合使用,如果include复用的布局和其上层布局是同一种布局,则可以使用merge标签减少嵌套层级: 在需要的时候加载。可以使用ViewStub标签来代替an
2020-11-09 22:19:17 865
原创 Android内存检测工具
什么是内存泄漏?在运行的程序中,如果一个无法访问的对象仍然占用着内存空间,即为此对象造成了内存泄漏垃圾回收(GC)机制:当垃圾回收运行时,虚拟机首先会识别GC Root。GC Root 是一个可以从堆外部访问的对象,它可以是本地变量或运行中的线程等。虚拟机会识别所有可以从GC Root访问的对象,它们将会被保留,而其他无法从GC Root访问的对象,则会被认为垃圾并回收掉。一、通过Memory Profiler检测内存泄漏打开 Memory Profiler,选中MEMORY ,进入MEMORY
2020-11-09 22:17:44 1414
原创 Android卡顿优化工具
一、BlockCanary 检测卡顿添加依赖:debugImplementation ‘com.squareup.leakcanary:leakcanary-android:1.5.4’releaseImplementation’com.squareup.leakcanary:leakcanary-android-no-op:1.5.4’配置BlockCanaryContext 关键属性:provideBlockThreshold 检测卡顿的阈值,单位毫秒(必须配置)onBlock 阻塞回调
2020-11-09 22:16:30 582
原创 深入理解JVM:HotSpot虚拟机对象探秘
一、对象的创建过程Java是一门面向对象的变成语言,在程序运行过程中无时无刻都有对象的创建。在语言层面上创建一个对象仅需要一个new关键而已,而在虚拟机中,对象(指普通对象,不包括数组和Class对象等)的创建又是怎样的过程呢?1、类加载检查当虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行类的加载过程注:常量池指的是运行时常量池,类加载后,在方法区的运行时常量池中存放。存放
2020-11-09 21:43:37 231
原创 深入理解JVM:Java内存模型与线程、线程安全及锁优化
七、Java内存模型与线程Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。1、Java内存模型1.1、主内存与工作内存Java内存模型规定了所有的变量都存储在主内存中。每条线程都有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程变量所有的操作(读取、赋值等)都必须在工作内存中进行,而不能直接读取主内存中的变量。线程间变量
2020-10-12 22:44:58 305
原创 深入理解JVM:类加载机制
加载—>校验—>准备—>解析—>初始化虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。3.1、加载-> 查找并加载类的二进制数据。加载是“类加载”(Class Loading)过程的一个阶段,虚拟机需要完成一下3件事:通过一个类的全限定名来获取定义此类的二进制字节流将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构在内存中生成一个代表这个类的jav
2020-10-09 23:22:55 304 2
原创 深入理解JVM:Class文件结构
Class文件是一组以8位字节为基础单位的二进制字节流,各个数据项目按照严格顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有间隙存在。当遇到需要占用8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。存储格式:Class文件采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表无符号数:无符号数属于基本数据类型,以u1、u2、u4、u8来分别代表1个字节、
2020-09-02 22:29:05 217 1
原创 深入理解JVM:垃圾回收机制
我们知道Java内存运行时数据区域划分为5个部分,其中程序计数器、虚拟机栈、本地方法栈3个区域随着线程而生,随着线程而灭;栈中每一个栈帧中分配的内存在编译期就已经确定下来,因此这几个区域的内存分配与回收都具备确定性。而Java堆和方法区,这部分的内存分配与回收是动态的,是垃圾收集器所需要回收的关注回收的区域。在回收对象之前,首先要确定对象能否被回收。当一个对象不在被其它途径使用时,这个对象就可以被回收了。一、垃圾标记算法在堆里面存放着Java中几乎所有的对象实例,垃圾回收器在对堆进行回收前,首先需要
2020-08-31 23:22:01 250
原创 深入理解JVM:运行时数据区域划分
一、运行时数据区Java虚拟机在Java执行的过程中会将它所管理的内存区域划分为若干个不同的数据区域。Java7.0划分如下其中:线程共享:方法区、堆线程私有:虚拟机栈、本地方法区、程序计数器注:在Java8中移除了永久代(方法区),通过元数据区(meataspace)存储数据。元数据区本质与永久代类似,都是对方法区的实现。区别:元数据空间不在虚拟机中,而是使用本地内存1.1、程序计数器程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是记录当前
2020-08-31 22:08:02 577
原创 NestedScrollingParent 和 NestedScrollingChild 实现嵌套滚动
1、NestedScrollingParent 方法注释/** * 该接口应该由{@link android.view.ViewGroup ViewGroup}子类实现 * 希望支持嵌套子视图委托的滚动操作。 */public interface NestedScrollingParent { /** * 有嵌套滑动,询问该父View是否接受嵌套滑动 * * @param child 直接子类(层级 child >= target) * @pa
2020-07-23 06:55:51 571
原创 Android 使用 Scroller 实现平滑滚动
很早就知道Scroller是实现View平滑滚动的一种方式,但是一直没有机会使用。最近看RecyclerView滚动的时候发现也是使用的Scroller,所以决定在总结一次用法。一、自定义View中实现View的平滑滚动public class ScrollerView extends View { private Scroller mScroller; private Paint mPaint; /** * 屏幕拖动最小像素 */ privat..
2020-07-11 15:06:27 898
原创 View绘制流程和requestLayout()原理
我知道View的绘制流程分为 measure、layout、draw,那么一个View显示在Activity上的完整流程是什么呢?在Activity启动流程中,Activity创建会执行Activity的acttach()。1、Activity & attach()1.0、设置/初始化 WindowManager```java // 设置WindowManager mWindow.setWindowManager( (WindowManag
2020-06-14 22:10:20 514
原创 Android 使用MediaRecorder实现录音
Android开发中,实现录音的方式主要有两种:MediaRecorder 和 AudioRecord。两者区别在于MediaRecorder录制的文件是经过压缩的,需要设置编码器,录制的文件系统可以直接播放。而AudioRecord录制的是PCM格式的文件,录制的文件没有经过编码,需要使用AudioTrack播放。使用步骤一、添加权限添加录音胡权限: <uses-permission android:name="android.permission.RECORD_AUDIO" />
2020-05-10 17:07:18 2888
原创 Android Context 相关
Context 是上下文环境对象,在Android中经常会使用到。一、Context 关联类首先Context是一个抽象类,它常见的子类有:Application、Activity、Service、ContextImpl。这些类关系如下:说明:ContextImpl:1、 Application、Activity、Service通过attach() 调用父类ContextWrappe...
2020-03-03 17:35:30 151
原创 Android应用进程启动笔记
Android系统启动后,想要启动一个应用程序,首先需要创建并启动该应用所需的应用程序进程。AMS在启动应用程序时会检查这个应用程序所需的进程是否存在,不存在就会请求Zygote进程启动相应的进程。我们知道,Zygote在Java框架层会创建一个Socket的服务端,这个Socket用来等待AMS请求Zygote创建新进程。Zygote进程通过fork自身创建应用程序进程,这样应用程序进程就...
2020-02-20 16:16:39 323
原创 Android系统启动笔记
一、init进程启动init进程是Linux系统中用户空间的第一个进程,进程号固定为1。主要职责:创建共享内存空间,用于属性服务解析各个rc文件,并启动相应的属性服务进程,包括Zygote服务进程二、Zygote进程启动Zygote由init进程通过init.zygote.rc文件fork的。Zygote进程是Android系统的第一个Java进程(即虚拟机进程),Zygote是...
2020-02-17 16:04:37 283
原创 ListView源码阅读
listview的源码在此之前看过也不止一次了,但是现在想想好像也就停留在看过的样子,除此之外就没啥印象了。想想之前就是在瞎看,毕竟ListView加上AbsListview有一万多行代码了,瞎看的话确实啥都看不出来啥的。所以这次看的话我就带着几次问题来看就行了,毕竟把1万多行代码看完对很多人来说是不现实的。带着下面几个问题,再次看一下Listview源码:Listview的适配器模式A...
2020-01-17 10:53:57 397
原创 适配器模式
定义:适配器模式是将一个类的接口变换成客户端所期待的另一种接口,从而使原本因为接口不匹配而无法在一起工作的两个类能够在一起工作。适配器在生活中还是很常见的,下面就是一个其中一种:电源适配器,目的是将220V电压输出成12V就以电源适配器一个适配器模式的例子,我们生活电压是220V的,现在需要输出12V电压,通过电源适配器完成将220V转换成12V的作用。220V电压类V220:cl...
2020-01-16 09:39:13 230
原创 EventBus与反射
我发现看一段代码,可能当时看的会有点模糊,但过一段时间回来再看的时候会忽然有一种:噢,原来是这么回事的感觉。今天看EventBus源码的时候也有这种感觉。基本用法1、注册 EventBus.getDefault().register(this); @Subscribe(threadMode = ThreadMode.MAIN) public void onTestEve...
2020-01-07 09:46:54 398
原创 Android知识点总结
Android四大组件Activity、BroadcastReceiver、ContentProvider、Service四大组件生命周期方法和简单用法Activity生命周期方法onCreate()、onStart()、onResume、onPause()、onStop()、onDestroy()、onRestart()。BroadcastReceiver生命周期方法onR...
2019-12-26 16:31:04 312
原创 ContentProvider使用
作为四大组件之一,ContentProvider 算是我直接次数最少的一个了。主要作用是跨进程对数据进行增删改查等操作。一、创建ContentProvider 实例ContentProvider是一个抽象类。创建MyProvider类继承ContentProvider,实现6个抽象方法:onCreate、getType、query、insert、delete、update。onCreate(...
2019-12-25 10:49:04 421
原创 Android SQLite简单使用
一直都是用的数据库框架,今天复习的时候忽然发现好像不怎么会使用SQLite了,复习一下吧。首先继承创建一个SQLite辅助类SqlHelper,继承SQLiteOpenHelper一、SQLiteOpenHelperpublic class SqlHelper extends SQLiteOpenHelper { //数据库名 private static final Str...
2019-12-24 16:37:25 236
原创 Flutter 自定义Widget——风车实现
最近在做一个天气模块的时候,风力需要显示一个选择的风车,实现效果如下:需求分析我们可以把上面的效果拆分为两个部分实现:1、画一个风车的WindmillWidget2、旋转动画一、风车Widget实现风车Widget 效果如下:这里又可以把它拆分为如下三部分实现:3片扇叶中间的圆点圆柱圆点和圆柱都比较好实现,最主要还是三片扇叶的实现。扇叶的实现思路是:先在原点(0,0...
2019-12-23 15:35:08 551
原创 Flutter RxBus实现
刚刚使用RxDart简单实现了EvnetBus效果,github地址:flutter_rxbus用法一:在pubspec.yaml引入dependencies: flutter_rxbus: ^0.0.11、注册 ///注册接收T类型消息 RxBus.getInstance().register<T>((value) { });2、发送消息...
2019-12-13 14:15:21 479
原创 Flutter pageview indicator指示器实现
最近正好用到pageview,发现官方好像没有提供指示器。去pub上搜了一下indicator,点了star最多的一个看了下,发现他的刷新好像和我需要的不匹配。最后还是决定自己实现一下吧。效果图项目地址flutter_page_indicator源码pub上的项目indicator圆点好像都是用paint画的。我的第一印象其实就是最外层用Stack包裹,里面放普通圆点和当前位置圆点。...
2019-12-11 13:43:13 1998
原创 Flutter局部刷新
在Flutter中,如果我们想要更新页面中的某个widget的状态的话,一般会使用setState方法重走build方法来刷新。当页面布局复杂的时候,这样肯定是不行的。下面提供了两种局部刷新的方式,通过provider和StreamBuilder来实现局部刷新1、通过provider刷新首先在pubspec.yaml中添加provider依赖 # provider provider:...
2019-12-09 16:04:16 8154 8
原创 Flutter点击水波纹效果封装
在flutter中, 普通Widget是没有点击效果的,设置点击事件的时候点着没有感觉。可以利用Flutter提供的水波纹widget来对控件进行包裹,这样就有点击效果了。1、使用InkWell实现child点击水波纹效果class RippleWidget extends StatelessWidget{ final Function onTap; final Widget ch...
2019-12-05 15:37:46 1042
原创 BroadcastReceiver 工作过程
说道广播的使用,就不得不提它的两种注册方式,动态注册和静态注册。静态注册在程序启动加载manifest文件时候完成。因此这里就以动态注册来看一下BroadcastReceiver 的工作过程。注册广播BroadcastReceiver 是一个抽象的类,因此我们需要继承BroadcastReceiver 实现一个我们自己的广播类 class MyReceiver extends Broa...
2019-12-02 15:41:42 326
原创 Service启动流程
相对于Activity而言,Service就显得神秘了很多。因为Service一般都是在后台默默运行的。今天就来看看Service的启动流程。Service的启动方式我们知道Service有两种启动方式。startServicebindService不同启动方式Service的生命周期方法也存在不同:1、startService方式启动生命周期:onCreate -> on...
2019-11-30 14:07:05 722
原创 Activity的启动流程
Activity是Android应用与用户交互的界面,了解Activity的启动流程可以加深我们对Activity理解。sdk版本25一、发起启动Activity的请求通常我们会通过startActivity()来打开一个新的Activity。 startActivity(new Intent(this, SecondActivity.class));1、Activity & ...
2019-11-27 16:35:59 351
原创 android动画用法小结
项目中有很多交互都需要用到动画,有时候还是需要去网上找些资料,所有决定自己总结一下android动画常用方法。分类帧动画view动画(视图动画)属性动画帧动画即逐帧播放动画用法:在res/drawable文件新建资源文件anim_grass,如下<?xml version="1.0" encoding="utf-8"?><animation-list xml...
2019-11-15 21:35:28 142
原创 android应用崩溃重启
一、创建一个捕捉崩溃信息的BugHandler 类public class BugHandler implements Thread.UncaughtExceptionHandler { private static BugHandler instance; private Application application; private Thread.Uncaught...
2019-11-02 13:48:24 662
原创 View的事件体系总结
一、基础知识1、View的坐标系View的坐标系统是相对于父控件的,如下图: getTop(); //获取子View左上角距父View顶部的距离 getLeft(); //获取子View左上角距父View左侧的距离 getBottom(); //获取子View右下角距父View顶部的距离 getRight(); //获取子View右下角距父...
2019-11-02 09:59:11 421
原创 Flutter 在initState()方法中页面跳转异常
情景描述:1、需要在initState()中做一些判断,然后需要在initState()跳转页面2、在initState()中加载数据,显示加载弹框。之前遇到过第一种情况,可能需要在initState()中做页面跳转,后来想办法避免了。今天一不小心又遇到了,在initState()方法中有个loadData()方法,加载数据的。加载数据的时候,显示loading弹框实际就是跳转一个l...
2019-10-23 13:55:30 3650
原创 自定义Flutter loading弹框
先看效果图如下:在Flutter中,万物皆widget。所以这所谓的弹框其实也是一个widget。而现实弹框其实就是打开一个新的路由,只不过背景颜色设为透明色就行了。布局代码实现代码如下:class LoadingDialog extends Dialog { @override Widget build(BuildContext context) { return ...
2019-09-28 16:43:23 10962 3
原创 Flutter 使用Dio请求返回数据不是Json字符串,而是Json对象
今天用使用Dio加载数据的时候出现一个异常,就是返回的数据是一个json对象,而不是json字符串,导致无法使用json解析。错误返回如下:{title: book, content: think in java}正常数据应该是这样的:{"title":"book","content":"think in java"}经过一番查找后发现官网上有一段备注的:说当响应头的conten...
2019-09-28 14:45:53 7625 3
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人