implementation 可以在编译时隐藏自己的依赖,但运行时这个依赖对所有模块可见。目的是为了减少编译时间,依赖自己的模块不会因为这个依赖变更重新编译
A- – ->B- – ->C 当C修改后,只要重新编译B和C就好了,A不需要编译
implementation 可以在编译时隐藏自己的依赖,但运行时这个依赖对所有模块可见。目的是为了减少编译时间,依赖自己的模块不会因为这个依赖变更重新编译
A- – ->B- – ->C 当C修改后,只要重新编译B和C就好了,A不需要编译
我的车 tradexportprerelease://ads/9d79cd6e-83be-4efa-b8b8-00b63ada76ea/
二手车 tradexportprerelease://ads/ce8976e5-7820-488d-891f-5782caf0bb66/
新车 tradexportprerelease://ads/05bbad0e-e593-4f16-961a-07a5cce39b38/
购买 tradexportprerelease://ads
订单 tradexportprerelease://orders
聊天 tradexportprerelease://messages/83e34e5b-7772-4b6a-ba96-8556486d9eb4/
tradex://tradexport.com/ads
https://tradexport.com/ads
JVM 的内存区域可以分为两类:线程私有的区域和线程共有的区域。 线程私有的区域:程序计数器、JVM 虚拟机栈、本地方法栈 线程共有的区域:堆、方法区、运行时常量池
其实除了程序计数器,其他的部分都会发生 OOM
垃圾回收需要完成两件事:找到垃圾,回收垃圾。 找到垃圾一般的话有两种方法:
回收垃圾的话有这么四种方法:
新生代对象分为三个区域:Eden 区和两个 Survivor 区。
新创建的对象都放在 Eden区,当 Eden 区的内存达到阈值之后会触发 Minor GC,这时会将存活的对象复制到一个 Survivor 区中,这些存活对象的生命存活计数会加一。这时 Eden 区会闲置,当再一次达到阈值触发 Minor GC 时,会将Eden区和之前一个 Survivor 区中存活的对象复制到另一个 Survivor 区中,采用的是我之前提到的复制算法,同时它们的生命存活计数也会加一。
这个过程会持续很多遍,直到对象的存活计数达到一定的阈值后会触发一个叫做晋升的现象:新生代的这个对象会被放置到老年代中。 老年代中的对象都是经过多次 GC 依然存活的生命周期很长的 Java 对象。当老年代的内存达到阈值后会触发 Major GC,采用的是标记整理算法。
一. :Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity;
二.:ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;
三.:Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行;
四. :ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信;
五 :ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。
@Override
protected void onDraw(Canvas canvas) {
//背景色
canvas.drawARGB(255, 255, 156, 161);
//先绘制的是dst,后绘制的是src
drawDst(canvas, mPaint);
drawSrc(canvas, mPaint);
}
private void drawDst(Canvas canvas, Paint p) {
//画黄色圆形
p.setColor(0xFFFFCC44);
canvas.drawOval(new RectF(0, 0, W * 3 / 4, H * 3 / 4), p);
}
private void drawSrc(Canvas canvas, Paint p) {
//画蓝色矩形
p.setColor(0xFF66AAFF);
canvas.drawRect(W / 3, H / 3, W * 19 / 20, H * 19 / 20, p);
}
代码很简单,就是在onDraw()中先画了一个黄色圆形dst,然后再画了一个蓝色矩形src。
结果显示后绘制的蓝色矩形叠加在黄色圆形上了,这是正常的混合模式。
使用PorterDuffXfermod的CLEAR模式。修改onDraw方法如下:
@Override
protected void onDraw(Canvas canvas) {
//背景色
canvas.drawARGB(255, 255, 156, 161);
//先绘制的是dst,后绘制的是src
drawDst(canvas, mPaint);
//设置xfermode
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
drawSrc(canvas, mPaint);
//还原
mPaint.setXfermode(null);
}
在绘制蓝色矩形src时给paint设置了Xfermode为CLEAR模式;
发现绘制的蓝色矩形src结果成了白色矩形
这是为什么呢?
先看如下代码:
@Override
protected void onDraw(Canvas canvas) {
//背景色
canvas.drawARGB(255, 255, 156, 161);
int sc = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), null, Canvas.ALL_SAVE_FLAG);
//先绘制的是dst,后绘制的是src
drawDst(canvas, mPaint);
//设置xfermode
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
drawSrc(canvas, mPaint);
//还原
mPaint.setXfermode(null);
canvas.restoreToCount(sc);
}
这次我们发现绘制的这个蓝色矩形src好像“消失了”。并且发现dst与src两个图形的相交处显示的是背景色。
比较这两处代码不同之处在于这次绘制图形是放在canvas.saveLayer与canvas.restoreToCount中实现的。
关于savelayout的作用查一下可知:
分析一下原因:
“为什么第一次会出现白色矩形呢?”这个问题也就很好回答了,因为我们一开始是在canvas的默认layer上绘制的,当我们的矩形区域src被CLEAR模式绘制后,该区域变为透明。canvas该部分就成为透明了,但由于Activity背景本身是白色的所以最终显示就为白色了。
通过上面的实验和分析可以得出,CLEAR模式可以使两种图片相交处设置为透明。但我们把API Demo那张图拿出来后一看:“不对啊,不应该是全部透明么?”这里就是那张图给我们挖的坑了。我们仔细看下官方示例的代码是如何实现的:
// create a bitmap with a circle, used for the "dst" image
static Bitmap makeDst(int w, int h) {
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(0xFFFFCC44);
c.drawOval(new RectF(0, 0, w*3/4, h*3/4), p);
return bm;
}
// create a bitmap with a rect, used for the "src" image
static Bitmap makeSrc(int w, int h) {
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(0xFF66AAFF);
c.drawRect(w/3, h/3, w*19/20, h*19/20, p);
return bm;
}
这是其实现代码,我们可以看出这两个方法的目的就是创建两个图形用来演示PorterDuffXfermod的不同效果。但我们仔细一看就能发现有点问题了:
原来如此!所以在开发中万不可看着API Demo图无脑来选择一种自己想要的模式,这样会使你得不到自己想要的结果时摸不着头脑。接下来我们按照图形实际大小修改后可以得出另一张图:
1、关于硬件加速
在sdkversion>=11时,需要关闭硬件加速,否则 Mode.CLEAR 、 Mode.DARKEN 、 Mode.LIGHTEN 三种模式下绘制效果不正常。
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
//View从API Level 11才加入setLayerType方法
//关闭硬件加速
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
2、关于saveLayer
savelayer不是必须的,我们已经知道使用他的目的了;其实我们可以新建一个bitmap并在这上面进行绘制,最后将bitmap绘制到canvas上,其实原理是一致的。
说明:
在握手期间,如果URL的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口实现程序来确定是否应该允许此连接,如果回调内实现不恰当,默认接受所有域名,则有安全风险。
反例:
HostnameVerifier hnv=new HosernameVerifier(){
@Override
public boolean verify(String hostname,SSLSession session){
return true;
}
}
正例:
HostnameVerifier hnv=new HosernameVerifier(){
@Override
public boolean verify(String hostname,SSLSession session){
if("youhostname".equals(hostname)){
return true;
}else{
HostnameVerifier hv=HttpsURLConnection.getDefaultHostnameVerifier();
return hv.verify(hostname,session);
}
}
}
java.io.IOException: Permission denied
是因为动态权限问题
./gradlew clean -i assembleDebug
发现 连接dl.google.com超时
则使用http://ping.chinaz.com/网站ping下,找到dl.google.com对应的ip
在本地hosts中添加一条记录
203.208.43.66 dl.google.com
再编译就好了
recyclerView.setNestedScrollingEnabled(true);
https://www.jianshu.com/p/635970ac603a
https://hfutfei.iteye.com/blog/988374
https://www.cnblogs.com/frankliiu-java/articles/1759460.html
https://www.cnblogs.com/zhaoyan001/p/6365064.html
https://blog.csdn.net/android_gogogo/article/details/53376178
https://my.oschina.net/djone/blog/145057
https://blog.csdn.net/lv_fq/article/details/77836700
https://github.com/lvfaqiang/AndroidTestCode
https://github.com/osmandapp/Osmand
http://www.justlive.vip/blog/article/details/4199
https://github.com/jiaowenzheng/CustomTextView
http://www.cnblogs.com/TerryBlog/archive/2013/04/02/2994815.html
https://www.cnblogs.com/zhujiabin/p/5808232.html
https://github.com/Luction/AndroidRichText
https://blog.csdn.net/u014620028/article/details/54092723
https://www.cnblogs.com/zhujiabin/p/5808232.html
http://www.cnblogs.com/luction/p/3645210.html
https://www.jianshu.com/p/b87dddf02e04
https://juejin.im/post/5b13a5b8f265da6e3128d501
https://tonnyl.io/Spantastic-Text-Styling-With-Spans/
http://melonteam.com/posts/gei_ni_de_spannablestring_she_zhi_dian_ji_tai/
https://blog.51cto.com/kinbos/1348407
https://blog.csdn.net/c16882599/article/details/52913799
https://segmentfault.com/a/1190000006163046
https://blog.csdn.net/natloc/article/details/50849700
http://blog.hacktons.cn/2015/02/03/porterduff/
https://www.jianshu.com/p/d54e24efbd7b
https://github.com/MrAllRight/BezierView/
https://www.jianshu.com/p/a5c2f0359d31
https://www.jianshu.com/p/016534448bfe
100% — FF
95% — F2
90% — E6
85% — D9
80% — CC
75% — BF
70% — B3
65% — A6
60% — 99
55% — 8C
50% — 80
45% — 73
40% — 66
35% — 59
30% — 4D
25% — 40
20% — 33
15% — 26
10% — 1A
5% — 0D
0% — 00
click delay
addDisposable(RxView.clicks(view)
.throttleFirst(BTN_THROTTLE_DELAY_TIME, TimeUnit.MILLISECONDS)
.subscribe(v -> handlerClicked()) );
以上大概意思:重复依赖,重复了条目。
1、清除一下缓存:File->Invalidate Caches/Restart..
注意:
除开Gradle依赖类库之外,还可以在项目中的libs下静态方式添加类库。
若是使用静态方式添加jar类库的,请删除重复的jar。
2、编译前clean下
build.gradle中没有buildToolsVersion,配置一下就好了
Build command failed.
Error while executing process /Users/xx/Documents/software/android-sdk-macosx/cmake/3.6.4111459/bin/cmake with arguments {-H/Users/xx/Documents/qtt/RTC_Android_v1.2.1/qtt_test/app -B/Users/xx/Documents/qtt/RTC_Android_v1.2.1/qtt_test/app/.externalNativeBuild/cmake/debug/armeabi -GAndroid Gradle - Ninja -DANDROID_ABI=armeabi -DANDROID_NDK=/Users/xx/Documents/software/android-sdk-macosx/ndk-bundle -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Users/xx/Documents/qtt/RTC_Android_v1.2.1/qtt_test/app/build/intermediates/cmake/debug/obj/armeabi -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=/Users/xx/Documents/software/android-sdk-macosx/cmake/3.6.4111459/bin/ninja -DCMAKE_TOOLCHAIN_FILE=/Users/xx/Documents/software/android-sdk-macosx/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-16 -DCMAKE_CXX_FLAGS=}
(include) CMakeLists.txt
Open File
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!
Build command failed.
Error while executing process /Users/xx/Documents/software/android-sdk-macosx/cmake/3.6.4111459/bin/cmake with arguments {-H/Users/xx/Documents/qtt/RTC_Android_v1.2.1/qtt_test/app -B/Users/xx/Documents/qtt/RTC_Android_v1.2.1/qtt_test/app/.externalNativeBuild/cmake/release/armeabi -GAndroid Gradle - Ninja -DANDROID_ABI=armeabi -DANDROID_NDK=/Users/xx/Documents/software/android-sdk-macosx/ndk-bundle -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Users/xx/Documents/qtt/RTC_Android_v1.2.1/qtt_test/app/build/intermediates/cmake/release/obj/armeabi -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM=/Users/xx/Documents/software/android-sdk-macosx/cmake/3.6.4111459/bin/ninja -DCMAKE_TOOLCHAIN_FILE=/Users/xx/Documents/software/android-sdk-macosx/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-16 -DCMAKE_CXX_FLAGS=}
(include) CMakeLists.txt
Open File
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!
却换NDK版本,我用了android-ndk-r15b
ndk {
// abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
abiFilters 'armeabi-v7a', "armeabi"
}
Transformation<Bitmap> circleCrop = new CircleCrop();
if (data.imgUrl.endsWith("gif")) {
Glide.with(context)
.asGif()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.load(data.imgUrl)
.into(imageView);
} else if (data.imgUrl.endsWith("webp")) {
Glide.with(context)
.load(data.imgUrl)
.optionalTransform(circleCrop)
.optionalTransform(WebpDrawable.class, new WebpDrawableTransformation(circleCrop))
.into(imageView);
} else {
Glide.with(context)
.load(data.imgUrl)
.into(imageView);
}
因为在Activity设置了主题背景,导致没有设置背景的TextView默认带有了一个背景图片
顶点坐标信息
^
|
4 | 3
(1, -1, 0) <----------------- (1, 1, 0)
| | |
| | |
---------------------|------------------------->
| | |
| | |
V | V
(-1, -1, 0) <-----——----------- (1, -1, 0)
2 | 1
|
上三角形:3->4->2->3
下三角形:1->2->3->1
共向量:2->3
float *vertexData = new float[12]{
1f, -1f, 0f,
-1f, -1f, 0f,
1f, 1f, 0f,
-1f, 1f, 0f
}
材质坐标信息
^
|
4 | 3
(0, 1) ----------- (1, 1)
| |
| |
| |
-------(0, 0) ----------- (1, 0)------>
2 | 1
|
glTexParameteri
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GL_TEXTURE_2D: 操作2D纹理
GL_TEXTURE_MIN_FILTER: 缩小过滤
GL_TEXTURE_MAG_FILTER: 放大过滤
GL_LINEAR: 线性过滤,使用距离当前渲染像素中心最近的4个纹理加权平均值
着色器语言又叫Shader,有两个模块一个是顶点着色器,一个是片元着色器
ffmpeg -i 720.mp4 -pix_fmt yuv420p -s 424×240 out.yuv