
Android
文章平均质量分 68
Munt
这个作者很懒,什么都没留下…
展开
-
Android开发@IntDef完美替代Enum (枚举)
概要Enum 是 java 中一种包含固定常数的类型,当我们需要预先定义一些值时,我们使用 Enum,这样做通常为了在编译时期避免接受额外常量引起的错误。而且,Enum 增加了APK 的大小,比常量多5到10倍的内存占用,这是关于应用性能的最佳实践.使用 Enum 的缺点每一个枚举值都是一个对象,在使用它时会增加额外的内存消耗,所以枚举相比与 Integer 和 String 会占用更多的内存。较多的使用 Enum 会增加 DEX 文件的大小,会造成运行时更多的开销,使我们的应用需要更多转载 2022-02-04 17:05:27 · 880 阅读 · 0 评论 -
Fragment切换replace和(add-hide-show)
Fragment的切换中有两种方式----方式1使用replace直接切换;方式2使用add先添加Fragment,然后再使用hide隐藏不显示的Fragment,最后再用show将需要显示的Fragment显示出来下面将介绍下这两种方式:方式1:使用replace使用replace切换Fragment的代码如下:FragmentManager fm = getSupportFragmentManager();FragmentTransaction ft = fm.beginTran.原创 2022-01-20 14:25:20 · 2764 阅读 · 0 评论 -
RecyclerView用法--展示多种类型Item数据
如题,本文主要介绍RecyclerView的基本使用方法,像ListView一样展示多种类型的Item数据。首先构造一个实体类:ItemPO,用来表示每个Item代表的数据类型:import java.io.Serializable; public class ItemPO implements Serializable { private static final long serialVersionUID = 7879752396036182745L; private转载 2022-01-04 14:54:14 · 1172 阅读 · 0 评论 -
Android 7.0及其以上版本获取Mac地址
/** * 通过网络接口取 * @return */ private static String getNewMac() { try { List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces()); for (NetworkInterface nif : all) { ...原创 2021-12-16 15:38:32 · 677 阅读 · 0 评论 -
Android ImageView旋转动画抗锯齿简洁方式
通过画布配置:canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.PaintFlagsDrawFilter;impo原创 2021-12-15 10:09:34 · 2703 阅读 · 1 评论 -
Android Recyclerview设置Item之间的间距
其实不需要自定义LinearLayout.LayoutParams 跟RecyclerView.ItemDecoration。假设:要在recycleView的每条item的下加一个8dp的边距:第一步:在每个item的布局的根布局加上paddingBottom。<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/andr原创 2021-12-08 16:01:07 · 5424 阅读 · 2 评论 -
AndroidStudio 加载系统源码流程(一)
1.Android Studio 开启前配置:**调整内存大小: ** Android Studio需要大量的内存来加载Android源码,所以经常会遇到内存不足的问题, 需要加大内存.1.点击Help->Edit Custom VM Options, 比如 “-Xms4096m -Xmx4096m”2. 修改android-studio/bin/studio.vmoptions studio64.vmoptions 两个文件的以下属性就可以了-Xms2048m-Xmx2048m.原创 2021-12-01 15:08:21 · 2879 阅读 · 0 评论 -
Android Studio中解决framwork.jar和SDK api冲突的方法
Android Studio中解决framwork.jar和SDK api冲突的方法Android开发中,系统工程师可能需要在系统层添加接口,这些新加的接口在Android Studio应用调用时常常会因找不到接口而导致编译不通过。现以SetupWizard_oem应用为例来说明解决方法。一、添加相应的Jar包到编译环境。out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\classes-full-debug.jar取出该jar放置到原创 2021-11-26 15:04:33 · 1251 阅读 · 0 评论 -
使用Android Studio 开发 SystemUI
由于用sublime或没有完整依赖的Studio来开发SystemUI非常难受,所以有了这篇分享,目标是做到像普通应用一样在Android Studio里开发SystemUI,可以正常跳转,正常依赖,正常编译,一键安装。1. 将源码放置到成正常gradle项目的结构2. 将资源目录分类存放 sourceSets { main { res.srcDirs += "src/main/res-flyaudio" res....转载 2021-11-23 15:32:26 · 2340 阅读 · 0 评论 -
APP性能优化系列:内存优化-内存泄露详解
转自http://blog.youkuaiyun.com/a910626/article/details/50849760一.内存泄露概念 在java中,如果一个对象没有可用价值了,但又被其他引用所指向,那么这个对象对于gc来说就不是一个垃圾, 所以不会对其进行回收,但是我们认为这应该是个垃圾,应该被gc回收的。这个对象得不到gc的回收, 就会一直存活在堆内存中,占用内存,就跟我们说的霸着茅坑不拉屎的道理是一样的。这样就导致了内存的泄露。 为什么会内存泄露呢,根本原因就是一个永远不会被使用的对象,因为转载 2021-10-06 18:58:00 · 1550 阅读 · 0 评论 -
Android 技巧 —— Debug 判断不再用 BuildConfig
解决方案:使用 ApplicationInfo.FLAG_DEBUGGABLE反编译 Debug 包和 Release 包对比看看有没有区别,会发现他们 AndroidManifest.xml 中 application 节点的 android:debuggable 值是不同的。Debug 包值为 true,Release 包值为 false,这是编译自动修改的。所以我们考虑通过 ApplicationInfo 的这个属性去判断是否是 Debug 版本,如下:public class A原创 2021-09-27 19:22:58 · 992 阅读 · 1 评论 -
StrictMode使用详解
Android平台中(Android 2.3起),新增加了一个新的类,叫StrictMode(android.os.StrictMode)。这个类可以用来帮助开发者改进他们编写的应用,并且提供了各种的策略,这些策略能随时检查和报告开发者开发应用中存在的问题,比如可以监视那些本不应该在主线程中完成的工作或者其他的一些不规范和不友好的代码。StrictMode有多种不同的策略,每一种策略又有不同的规则,当开发者违背某个规则时,每个策略都有不同的方法去显示提醒用户:StrictMode的策略和规...原创 2021-07-08 15:39:31 · 732 阅读 · 0 评论 -
android之生命周期onSaveInstanceState()状态保存
android生命周期图:各个方法之间的调用关系图 当用户在开启一个新activity时,当前的activity可能在内存中处于停止状态也可能由于新activity需要更多内存而被系统杀掉了,但不论怎样,当用户在新activity上按返回键时,他希望看到的是原先的activity的界面。原先的activity如果是被重新创建,那么它要恢复到用户最后看到它的样子。那么我们怎么做呢?其实也不难,跟据上一节所述,在onPause()或onStop()或onDestyroy()中保存必要的数据就行了。..原创 2021-06-30 11:54:31 · 1286 阅读 · 1 评论 -
Android进程启动流程(App启动)
站在GITYUAN大神的肩膀上学习,用一张神图表示进程基本的启动流程.站在GITYUAN大神的肩膀上学习,用一张神图表示进程基本的启动流程.上图还需对照源码进行查看,简述一下启动流程:<p>在Android系统全貌描述到了Zygote孵化了第一个进程是system_server进程,而且孵化第一个App进程是Launcher,也就是桌面App。<p>当点击桌面App的时候,发起进程就是Launcher所在的进程,启动远程进程,利用Binder发送消息给syste转载 2021-02-19 14:23:04 · 645 阅读 · 0 评论 -
Looper.loop为什么不会阻塞掉UI线程?
要完全彻底理解这个问题,需要准备以下4方面的知识:Process/Thread,Android Binder IPC,Handler/Looper/MessageQueue消息机制,Linux pipe/epoll机制。总结一下主要有3个疑惑:1.Android中为什么主线程不会因为Looper.loop()里的死循环卡死?2.没看见哪里有相关代码为这个死循环准备了一个新线程去运转?3.Activity的生命周期这些方法这些都是在主线程里执行的吧,那这些生命周期方法是怎么实现在死循环体外能够转载 2021-02-16 21:40:24 · 626 阅读 · 0 评论 -
onResume中Handler.post(Runnable)为什么获取不到宽高?
一般需求中会出现在Activity启动中需要获取Ui控件相关大小或者在界面绘制完成之后刷新数据,我们都知道在UI绘制完成之后,时机最好,不会阻塞主线程导致卡顿或者UI控件参数获取失败。也许大家使用过或 知道Handler(MainLooper).Post(Runnable)和View.Post(Runnable)都是把Runnable封装成Message再 push到主线程中looper中MessageQueue中,会发现在Activity的生命周期中执行这两种方式效果不同,前者不满足我们的需求,而后者转载 2021-02-14 22:38:29 · 456 阅读 · 0 评论 -
Android面向切面编程(AOP)
一、简述1、AOP的概念AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。2、项目场景项目开发过程中,可能会有这样的需求,需要我们在方法执行完成后,记录日志(后台开发中比较常见~),或是计算这个方法的执行时间,在不使用AOP的情况下,我们可以在方法最后调用另一个转载 2021-02-12 22:22:41 · 321 阅读 · 0 评论 -
NestedScrollingParent & NestedScrollingChild
嵌套滚动:NestedScrollingParent和NestedScrollingChild,这两个东西,可能好多人有点陌生,但我们在很多场景下,已经在不识不觉中使用它了,比如说CoordinatorLayout,它是一个NestedScrollingParent,还有RecycleView,它是一个NestedScrollingChild。一个最常见的效果:列表向上滚动,ToolBar收起,反之,当列表向下滚动时,ToolBar随着列表的滚动出现。这个效果,用NestedScrolling来实现,.转载 2021-02-08 23:23:37 · 588 阅读 · 0 评论 -
PagerAdapter中的NotifyDataSetChanged
我们知道ViewPager设置PagerAdapter之后通过notifyDataSetChanged方法也可以更新ViewPager,那么这是怎么实现的呢?答案是观察者模式。我们来看一下关于notifyDataSetChange()的源码:/** * This method should be called by the application if the data backing this adapter has changed * and associated views should转载 2021-02-05 17:19:58 · 440 阅读 · 0 评论 -
PagerAdapter的instantiateItem方法的执行次数
之前以为ViewPager每次滑动都会调用instantiateItem,后来做项目时发现有时滑动时并不执行写在instantiateItem中的一些更新操作。于是写了个demo测试一下,代码如下:import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.support.v4.view.PagerAdapter;原创 2021-02-04 18:04:07 · 644 阅读 · 1 评论 -
Android DiskLruCache解析,硬盘缓存的最佳方案
概述记得在很早之前,我有写过一篇文章Android高效加载大图、多图解决方案,有效避免程序OOM,这篇文章是翻译自Android Doc的,其中防止多图OOM的核心解决思路就是使用LruCache技术。但LruCache只是管理了内存中图片的存储与释放,如果图片从内存中被移除的话,那么又需要从网络上重新加载一次图片,这显然非常耗时。对此,Google又提供了一套硬盘缓存的解决方案:DiskLruCache(非Google官方编写,但获得官方认证)。只可惜,Android Doc中并没有对DiskLruC转载 2021-02-04 17:23:21 · 323 阅读 · 0 评论 -
Android Service保活
保活Service我们需要做什么:1.在应用被关闭后保活2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service)3.重启手机后自动开启Service4.手机息屏后不被释放内存5.手动清理内存时保活Android进程的生命周期与大家比较熟悉的Activity生命周期相比,Android进程的生命周期实质更为简单,越核心的东西越简单嘛,Android将一个进程分为五种不同的状态:一、前台进程 Foreground process二、可见进程 Visible原创 2021-02-02 10:59:10 · 1729 阅读 · 0 评论 -
Android View视图层次
其实在DecorView中还有一个id为statusBarBackgroud和一个id为navigationBarBackground的View,分别表示手机的顶部的状态栏和手机底部的导航栏。Activity中加载布局,都是通过在onCreate中调用setContentView方法开始:@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method..转载 2021-02-01 20:59:37 · 1852 阅读 · 0 评论 -
Android沉浸式状态栏(透明系统状态栏)
Android沉浸式状态栏(透明系统状态栏)的目的:顶部系统状态栏和App的导航栏一体化,不给用户突兀的感觉,使用户把更多的视角留在我们的App上。沉浸式状态栏的兼容情况Android版本 透明状态栏 <4.4 × 4.4-5.0 ✓ >=5.0 ✓ Android版本 黑白字符状态栏 <6.0 × >=6.0 ✓ fitsSystemWindowsfitsSystemWindows,这个属性在沉.原创 2021-02-01 14:30:34 · 5480 阅读 · 0 评论 -
HttpURLConnection方式直接下载文件
protected void downloadAPK(String downloadUrl) { File downloadFile = null; if (TextUtils.isEmpty(downloadUrl)) return; HttpURLConnection connection = null; try { Thread.currentThread().setPriority(Thread.MIN_PRIORITY); URL url = new URL(d.原创 2021-01-26 16:50:46 · 3331 阅读 · 0 评论 -
Handler优化弱引用的疑问
对于对象的四种引用相信大家都不陌生,由强到弱分别是:强引用、软引用、弱引用和虚引用。强引用无法被GC回收,当内存不足时报OOM。软引用如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。弱引用如果一个对象只具有弱引用,那么在垃圾回收器线程扫描的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。一般平时用的最多的地方,可能就是handler了1、优化handler为何选择弱引用而不选原创 2021-01-26 15:49:33 · 337 阅读 · 0 评论 -
JNIEnv的使用在C和C++中的区别&jclass和jobject
Java调用C和C++函数时的JNI使用区别:注意:jni.h头文件中对于***.c & ***.cpp采用不同的定义在C的定义中,env是一个两级指针,而在C++的定义中,env是个一级指针C形式需要对env指针进行双重deferencing,而且须将env作为第一个参数传给jni函数jclass (JNICALL *GetObjectClass) (JNIEnv *env, jobject obj);jclass GetObjectClass(jobject .原创 2021-01-20 15:33:45 · 814 阅读 · 0 评论 -
进程间通信(IPC) 相关
通过引入相关问题来进行思考阐述:1.简述 IPC?IPC 就是指进程之间的通信机制,在 Android 系统中启动 Activity/Service 等都涉及跨进程调用的过程。2.Android中的IPC 方式有哪些:Bundle,文件共享,Messenger,AIDL,ContentProvider,Socket等3.如何开启Android中的多进程:(常规)在AndroidMenifest中给四大组件指定属性android:process。 (不常规)通过JNI在na原创 2020-12-30 14:19:34 · 140 阅读 · 0 评论 -
Android深入理解RecyclerView的缓存机制
讲一下RecyclerView的缓存机制,滑动10个,再滑回去,会有几个执行onBindView。缓存的是什么?cachedView会执行onBindView吗?这两个问题都是关于缓存的,我就一起说了。1)首先说下RecycleView的缓存结构:Recycleview有四级缓存,分别是mAttachedScrap(屏幕内),mCacheViews(屏幕外),mViewCacheExtension(自定义缓存),mRecyclerPool(缓存池) mAttachedScrap(屏幕内).转载 2020-12-24 21:33:54 · 1361 阅读 · 1 评论 -
RecyclerView的局部更新
RecyclerView的刷新可以分为列表重新加载刷新、item刷新、item中局部刷新。对于前两种的刷新,都会是的列表刷新的时候闪烁一下,而后者则看不出列表有任何闪烁,并且,局部刷新能在一定程度上减少不必要的UI绘制渲染RecyclerView 数据刷新的几种方式,RecyclerView 真正的布局刷新的正确方式notifyDataSetChanged()刷新全部可见的itemnotifyItemChanged(int position)更新列表position位置上的数据可以调用n..原创 2020-12-24 14:08:49 · 1749 阅读 · 1 评论 -
Android View 滑动冲突解决方式以及原理
一. 滑动冲突场景以及产生原因产生滑动冲突的场景主要有两种:父ViewGroup和子View的滑动方向一致 父ViewGroup和子View的滑动方向不一致那为什么会产生滑动冲突呢,例如在父ViewGroup和子View的滑动方向一致的情况,我需要让两者都可以滑动。在事件分发机制中,ViewGroup的onInterceptTouchEvent方法默认情况下是返回false,也就是ViewGroup默认情况下是不会拦截事件的。当ViewGroup接收到事件时,由于不拦截事件,会去寻找能够处理事件转载 2020-12-24 10:27:27 · 658 阅读 · 0 评论 -
StaticLayout的使用详解
在Android开发中,Canvas.drawText不会换行,即使一个很长的字符串也只会显示一行,超出部分会隐藏在屏幕之外。StaticLayout是android中处理文字的一个工具类,StaticLayout 处理了文字换行的问题。在Staticlayout的中构造参数有三个: public StaticLayout(CharSequence source, TextPaint paint, int width,原创 2020-12-10 15:32:58 · 1764 阅读 · 1 评论 -
Android里循环执行定时常用两种方法
第一种:Handler+Runnable实现方式实现循环执行定时//1,首先创建一个Handler对象Handler handler=new Handler(); //2,然后创建一个Runnable对像Runnable runnable=new Runnable(){ @Override public void run() { // TODO Auto-generated method stub //要做的事情,这里再次调用此Runnable对象原创 2020-12-07 23:17:09 · 8116 阅读 · 1 评论 -
Android解惑之Handler为什么需要是static的
我们先来看一张Android Studio中的warning截图handler内存泄漏.png上面这段代码会引起内存泄漏(Memory Leak)。 为什么会引起内存泄漏? 我们都知道,非static的内部类会持有外部类的引用,举个类子来说,我们经常在一些内部类中显示跳转activity的时候,给Intent赋值的时候,第一个参数会写 外部类名.this ,这就是持有外部类的引用的很好表现。 同样,其他地方需要用到这个内部类的时候,也不能是直接new出来,因为为非static的,必转载 2020-12-02 18:42:12 · 690 阅读 · 0 评论 -
View.onDraw(Canvas canvas)
一般UI控件不满足我们的需求的时候,就需要自定义View。自定义view的一个重点就是实现去重写他的绘制过程,也就是View.onDraw(Canvas canvas)方法,它里面就是绘制图形的过程了,比如说一个Button,绘制按钮和按钮上的文字都是在它自己的onDraw方法中完成的。如果你想给ImageView加个蒙版,可以继承ImageView并且重写他的onDraw方法,调用完父类的onDraw之后,再自己Canvas来画一个黑色的半透明矩形,这样就可以对现有的控件进行加工了。Canvas是画布原创 2020-11-27 15:21:20 · 1149 阅读 · 0 评论 -
HttpURLConnection 中Cookie 使用
因为公司项目中一开始请求网络数据,发现没有看到关于带上cookie 的网络请求,对此一直很有疑惑。直到偶然看到一段话恍然大悟如果想通过 HttpURLConnection 访问网站,网站返回cookie信息,下次再通过HttpURLConnection访问时,把网站返回 cookie信息再返回给该网站。可以使用下面代码。CookieManager manager = new CookieManager();CookieHandler.setDefault(manager);通过这两行代码转载 2020-11-18 21:46:22 · 1838 阅读 · 1 评论 -
ANDROID开发中渠道包过多时GRADLE过滤处理
def local_props = new Properties()if(file("local.properties").exists()) file("local.properties").withInputStream { local_props.load(it) }def buildFlavor = local_props.getProperty('build.variantName')有些公司App需要大力推广,所以会要求打大量的渠道包,这样gradle文件里面会产生一堆配置,..原创 2020-11-13 16:39:30 · 602 阅读 · 0 评论 -
viewpager+fragment +多图内存溢出问题
viewpager+fragment +多图 简直要命,滑动到一定数量的fragment左右就会内存溢出说是内存溢出,其实是内存泄漏。图片加载开源库有很多,我用的是Glide,Glide会回收图片释放内存,然而如果该图片一直被imageview保持引用就会出现无法回收的状态,最终这些图片越来越多,导致内存溢出。然后要解决的问题就是在适当的时间释放掉这些引用。这里以viewpager和fragment配合使用为例,当然是以fragment为一个单位,那么在fragment的onDestroyV转载 2020-11-09 22:03:34 · 720 阅读 · 0 评论 -
ImageView 加载图片方法
关于ImageView,常很容易混淆background 和 src 两个属性的特征:(1)background通常指的都是背景,而src指的是内容。(2)当使用src填入图片时,是按照图片大小直接填充,并不会进行拉伸。代码用法设置:一.设置ImageView的src:1.image.setImageDrawable(getResources().getDrawable(R.drawable.vod_detail_actor_default));2.String path=Envi.原创 2020-10-26 11:54:14 · 2109 阅读 · 0 评论 -
Activity中onNewIntent()方法触发及注意事项
Activity的onNewIntent()方法何时会被调用?前提:ActivityA已经启动过,处于当前应用的Activity堆栈中;当ActivityA的LaunchMode为SingleTop时,如果ActivityA在栈顶,且现在要再启动ActivityA,这时会调用onNewIntent()方法;当ActivityA的LaunchMode为SingleInstance,SingleTask时,如果已经ActivityA已经在堆栈中,那么此时再次启动会调用onNewIntent()方原创 2020-10-26 11:49:20 · 3249 阅读 · 0 评论