Android基础_Aron
2017-05-19 11:24:42 0 举报
AI智能生成
登录查看完整内容
Android,工作中的一些总结,喜欢就点个赞吧
作者其他创作
大纲/内容
功能
数据存储
文件存储
网络存储
OkHttp+Glide
允许开发者将Image的二进制文件下载到硬盘缓存当中,以便在后续使用
下载完毕之后如果想要进行显示,可以通过如下方式进行调用:Glide.with(yourFragment) .load(yourUrl) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(yourView);
ListPreloader如果你想让列表预加载的话,不妨试一下ListPreloader这个类。
缓存
子主题
调用diskCacheStrategy(DiskCacheStrategy.ALL)让Glide既缓存全尺寸又缓存其他尺寸
接口缓存
Android安卓获取网络状态
数据库存储
共享参数
sharedPreferences简介
获取该对象的方式
调用Context对象的getSharedPreferences()方法
同一个context的组件都能使用
调用Activity对象的getPreferences()方法
该对象只能在该Activity中使用
四种操作模式
Context.MODE_PRIVATEContext.MODE_APPENDContext.MODE_WORLD_READABLEContext.MODE_WORLD_WRITEABLE
存取数据
SharedPreferences preferences=getSharedPreferences(\"user\
应用
是否第一次运行
SharedPreferences sharedPreferences = this.getSharedPreferences(\"share\
文件上传
选择文件
SD卡路径
SD卡权限
上传网络权限
Bitmap处理
byte[]<--->Bitmap
上传图片命名
通信(值回传)
startActivityForResult
广播
接口回调
推送
广播Receiver
广播声音振动
Notification自定义声音
代码执行点击
代码卸载
密钥
百度
SHA1 Android签名证书的sha1值+“;”+packagename(即:数字签名+分号+包名)
获取Android系统的唯一识别码
友盟
输入名称即可
极光
申请需要包名
包名替换
技能\\技巧
Debug调试
span style=\
调试技巧
打印调用栈
三
// 创建异常打印堆栈 Exception e = new Exception('this is a log'); e.printStackTrace();
AS获取SHA1
暗码
如user版本或者userdebug版本手机usb没有dai口话,请进入*#*#9738#*#*,把dai口的开关打开 烧user版本的话,如需要打开root的权限的话,请进入*#*#9738#*#* 需要打开oemroot开关
Android版本
API
4.4 KITKAT = 19
4.4
奇巧
KITKAT_WATCH = 20
4.4W
21
5.0
Lollipop
22
5.1
5.1.1 Api22 LOLLIPOP_MR1
23
6.0
Marshmallow
棉花糖
6.0 Api23 M
24
7.0
Nougat
牛轧糖
7.0 Api24
16
25
7.1.1 Api
161206: 加入类似“3D Touch”功能
26
Android8.0
O
Notification.setNumber 用于launcher显示数量
27
Android 8.1
O Oreo
奥利奥
28
Android 9.0
Pie
馅饼
29
Android 9.+
Q
新版本新特性
TextView
设置锁屏
Y3
修改默认桌面布局
1.改Launcher中的default_workspace.xml
2.\u00A0Z:\\zs_1.0\\device\\zeusis\\Y3\\cust\\CUST-CHINA\\
ALL\\General\\default_workspace.xml
CMCC\\China\\default_workspace.xml
CTCC\\China\\default_workspace.xml
CUCC\\China\\default_workspace.xml
GMS 演示版
验证桌布布局
push ..\\default_workspace.xml data\\cust\\ 没用
已经root但提示仅读文件
cust 指向 cust/ALL/General
改文件模式
没用
push ..\\default_workspace.xml cust/ALL/General
rm data/data/com.journeyui.zslauncher
重启
背屏应用
Y3:/system/presetapp # lsAiQiYi IreaderA MiguA ShangYeZhouKangB TongHuaShunA YingYongBaoAmap IreaderB MiguB SinaWeibo TongHuaShunB iReaderBaiduInput JieMian NewsRepublic_ares_ww SogouSearch_pollux Toutiao_pollux letvplayerBaiduSearch JieMianA QQReaderA SohuNewsClient_pollux VoiceAssistant letvplayer_polluxBaoLiTest Jingdong_pollux QQReaderB TecentNews WPSOfficeCloudMusic_cmcc KuwoPlayer QQTongBuZhuShou TencentVideo WechatCtrip MeiTuan Qunar_pollux TencentVideo_pollux Weibo_polluxHappyelements_pollux Meituan_pollux ShangYeZhouKangA TencentWifiManager Wps
插件化
问题
问题:插件不在BLauncher当前显示页时,也会在后台同步数据或弹dialog或弹toast问题产生原因:BLauncher使用的是ViewPager,滑动时会预加载多个插件要求: 1.当滑出插件页时,主动dismiss已弹dialog 2.当滑出插件页时,主动让显示的toast消失 3.当滑入插件页时,才能弹dialog或Toast 4.当滑出插件页时,主动停止界面的数据刷新和后台的数据同步技术方案: 1.滑入插件页时,BLauncher会调用插件的switchToThisPage()方法 2.滑出插件页时,BLauncher会调用插件的switchOffThisPage()方法
Android基础_Aron
系统
包名
子主题 1
android获取已安装应用的安装包
拨号
资源文件
Drawable
弹框消失
键盘
隐藏键盘
搜索的时候 获取键盘的回车
颜色相关
android\u00A0在代码中使用\u00A0#ffffff\u00A0模式\u00A0设置背景色
4种设置颜色
返回int
Color.parseColor(\"#dd0000\")
常用颜色
子主题 4
在使用shape的同时,用代码修改shape的颜色属性
使用资源文件的颜色
透明度
组件
Activity
值回传
回传到Fragment
移除之前的所有activity
更改背景透明度
Intent
跳多个intent
启动另一个App
OnKeyDown
启动背屏
最近任务的方式启动应用
通过taskId启动任务栈
获取运行的task
ActivityManager m = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);List runningTaskInfoList = m.getRunningTasks(1);if(!runningTaskInfoList.isEmpty()) { String callingPackageName = runningTaskInfoList.get(0).baseActivity.getPackageName();}
ContentProvider内容提供者
简介
基本使用
系统联系人
查询
权限
<uses-permission android:name=\"android.permission.READ_CONTACTS\"></uses-permission>
插入
自定义ContentProvider
新建一个类继承ContentProvider
AndroidManifest.xml
声明provider
android:export=true
api16以上默认false
广播类型
静态注册
优点:不受应用生命周期的影响,常驻 缺点:常驻会耗费cpu、电量等资源
动态注册
优点:在Android的广播机制中,动态注册的优先级高于静态注册的优先级,因此在必要情况下,我们需要动态注册广播接收器。取消注册后,不再占用资源 缺点:程序退出,注销广播后,便无法进行广播监听
示例
存储不足
Service
启动startService
绑定bindService
四大组件之间的通信
Activity和Service
通过Binder对象
即bindServcie启动
广播接收器
属性配置
手机IMSI/IMEI
IMSI
String android_imsi = telephonyManager.getSubscriberId();//获取手机IMSI号 String IMSI = android.os.SystemProperties.get( android.telephony.TelephonyProperties.PROPERTY_IMSI);
IMEI
唯一的设备ID: GSM手机的 IMEI 和 CDMA手机的 MEID.
String imei = ((TelephonyManager) context.getSystemService(TELEPHONY_SERVICE)).getDeviceId();
在manifest.xml文件中要添加 <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />
Y3得到的IMEI是null
String IMEI = android.os.SystemProperties.get(android.telephony.TelephonyProperties.PROPERTY_IMEI)
不过纯APP开发SystemProperties,TelephonyProperties汇报错误,因为android.os.SystemProperties在SDK的库中是没有的,需要把Android SDK 目录下data下的layoutlib.jar文件加到当前工程的附加库路径中,就可以Import。
手机号
TelephonyManager tm= (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);String number = tm.getLine1Number();
版本号
AndroidManifest.xmlandroid:versionCode=\"1\"android:versionName=\"1.0\"
手机型号
String DeviceName = android.os.Build.DEVICE
工具
ADB
adb被占用时
Mac ADB
MX4 Pro ADB
查看签名指纹证书(SHA1)
keytool -list -keystore E:\\Turbo\\AndroidStudioProjects\\mykey.jks
keytool -list -keystore .\\keystore\\platform.jks
keytool -list -keystore mykey_new.store
keytool在
事件分发
场景1
问题: frameLayout 或ViewGroup事件穿透到下层
需要拦截事件给自己或子类消费
setClickable true
android:clickable=\"true\"
把父类的touch事件分给自己处理
View相关
View转Bitmap
问题:buildDrawingCache()导致ViewGroup中child.mFlagView为空
drawableId转 Bitmap
自定义宽高和模式ARGB_8888 or RGB_565
基础
[Android入门:File文件存储]
文件目录
context或Activity
getFilesDir()方法用于获取/data/data//files目录
getAbsolutePath()
获取绝对路径
getPath()
getCacheDir()方法用于获取/data/data//cache目录
Environment.getExtemalStorageDirectory()
获取SDCard的目录
SD卡状态
Environment.getExtemalStorageState()
Environment.MEDIA_MOUNTED
简单示例
File saveFile=new File(\"/sdcard/zhzhg.txt\");或:File sdCardDir=new File(\"/sdcard\
文件模式Mode
注意,如果希望其他使得文件模式叠加,则可以使用加号连接;比如:Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE 表示其他应用读写;
chmod 777 fileName
文件改成 rwx rwx rwx
文件操作
计算文件夹大小
/** * 获取文件夹大小 * @param file File实例 * @return long */ public static long getFolderSize(java.io.File file){ long size = 0; try { java.io.File[] fileList = file.listFiles(); for (int i = 0; i < fileList.length; i++) { if (fileList[i].isDirectory()) { size = size + getFolderSize(fileList[i]); }else{ size = size + fileList[i].length(); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } //return size/1048576; return size; }
格式化单位
/** * 格式化单位 * @param size * @return */ public static String getFormatSize(double size) { double kiloByte = size/1024; if(kiloByte < 1) { return size + \"Byte(s)\
文件Copy
拷贝assets目录下文件
InputStream is = ctx.getAssets().open(\"test.apk\");
文件压缩
GZipOutputStream
BufferedOutputStream out = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(\"test.txt.gz\")));
追加写入文件内容
追加文件:使用FileOutputStream,在构造FileOutputStream时,把第二个参数设为true
文件重命名
File file = new File(oldPath); file.renameTo(new File(newPath));
第一,如果是Android的SD卡上的文件重命名,那么必须添加权限:<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />第二,oldPath和newPath必须是新旧文件的绝对路径
选择照片
OkHttp上传
无进度条
带进度条
设计模式
单例模式
恶汉式-简单快捷
public class Singleton{ //在自己内部定义自己的一个实例,只供内部调用 private static final Singleton instance = new Singleton(); private Singleton(){ //do something } //这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance(){ return instance; }}
instance在类装载时就实例化,虽然导致类装载的原因有很多种在单例模式中大多数都是调用getInstance方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。
恶汉式-变种
public class Singleton { private Singleton instance = null; static { instance = new Singleton(); } private Singleton (){} public static Singleton getInstance() { return this.instance; } }
表面上看起来差别挺大,其实跟简单恶汉式差不多,都是在类初始化即实例化instance。
懒汉式-线程安全
public class SingletonClass{ private static volatile SingletonClass instance=null; public static SingletonClass getInstance(){ synchronized(SingletonClass.class){ if(instance==null){ instance=new SingletonClass(); } } return instance; } private SingletonClass(){}}
public class SingletonClass{ private static SingletonClass instance=null; public static synchronized SingletonClass getInstance(){ if(instance==null){ instance=new SingletonClass(); } return instance; } private SingletonClass(){ }}
双重校验锁-提高效率
public class Singleton{ private static volatile Singleton instance=null; private Singleton(){ //do something } public static Singleton getInstance(){ if(instance==null){ synchronized(SingletonClass.class){ if(instance==null){ instance=new Singleton(); } } } return instance; }}
懒汉式-线程不安全
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
关闭进程
强制关闭进程
try { final String command = \"am force-stop com.android.jv.ink.launcherink\"; Process process = Runtime.getRuntime().exec(command); } catch (IOException e) { e.printStackTrace(); }
关闭
android.os.Process.killProcess(android.os.Process.myPid());
时间日期
UI控件
获取时间
Date
设置当前时间
SimpleDateFormat sdf = new SimpleDateFormat(\"yyyy-MM-dd\");timeTextView.setText(sdf.format(new Date()));
当前时间戳
String.valueOf(System.currentTimeMillis())
Calendar
Calendar c = Calendar.getInstance();int curYear = c.get(Calendar.YEAR);curMonth = c.get(Calendar.MONTH) + 1;curHours = c.get(Calendar.HOUR_OF_DAY);
定时器
2s不可点击
long mBtnLastClick = 0; // 字段
if (System.currentTimeMillis() - mBtnLastClick < 2000) { return; } mBtnLastClick = System.currentTimeMillis();
2s后执行
Handler + Runnable
Timer+TimerTask
开个子线程sleep2秒
定时重复任务
Timer & TimerTask
TimerAndroid 的 Timer 类可以用来计划需要循环执行的任务,Timer 的问题是它需要用 WakeLock 让 CPU 保持唤醒状态,这样会大量消耗手机电量,大大减短手机待机时间。这种方式不能满足我们的需求
AlarmManager
AlarmManagerAlarmManager 是 Android 系统封装的用于管理 RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在 CPU 休眠时正常运行,在预设的时间到达时,通过中断唤醒 CPU。这意味着,如果我们用 AlarmManager 来定时执行任务,CPU 可以正常的休眠,只有在需要运行任务时醒来一段很短的时间。
JobSchedule
安卓5.0以后为了省电
app 耗电优化之三 使用JobSchedule对任务进行合理排期
Handler + Runnable2s后重复执行
3. 停止计时器[java] view plaincopyhandler.removeCallbacks(runnable);
第三方库的选择
Android事件分发中心库_鸿洋
Gradle
1.多渠道打包
AndroidManifest.xml中修改以下值:<meta-data android:name=\"UMENG_CHANNEL\" android:value=\"wandoujia\" />首先你必须在AndroidManifest.xml中的meta-data修改以下的样子:<meta-data android:name=\"UMENG_CHANNEL\" android:value=\"${UMENG_CHANNEL_VALUE}\" />
productFlavors { wandoujia {}baidu {}c360 {}uc {} productFlavors.all { flavor ->flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]} }
这样生成apk时,选择相应的Flavors来生成指定渠道的包就可以了,而且生成的apk会自动帮你加上相应渠道的后缀,非常方便和直观。大家可以自己反编译验证。
先找到gralde的根目录,在系统变量里添加两个环境变量:变量名为:GRADLE_HOME,变量值就为gradle的根目录;所以变量值为:C:\\Users\\yazhou\\.gradle\\wrapper\\dists\\gradle-2.1-all\\27drb4udbjf4k88eh2ffdc0n55\\gradle-2.1还有一个在系统变量里PATH里面添加gradle的bin目录我的就是C:\\Users\\yazhou\\.gradle\\wrapper\\dists\\gradle-2.1-all\\27drb4udbjf4k88eh2ffdc0n55\\gradle-2.1\\bin这里配置完成了,接着在Terminal中敲下 gradle assembleRelease就可以一次性生成所有的渠道包了。所有生成的apk在项目的build\\outputs\\apk下。
如果只是想生成单个渠道的包呢?打开Android Studio的Gradle tasks面板(右边侧边栏),会发现模块多了很多任务,如下图所示。
多渠道配置源码路径
sourceSets { // userDebug版本 userDebug {// manifest.srcFile 'src/coolYota/AndroidManifest.xml'// java.srcDir 'src/usefull/yotadevice/java' } // 用户版本 user {// java.srcDir 'src/unusefull/yotadevice/java' } }
Maven仓库
上传到本地指定目录
apply plugin: 'com.android.library'apply plugin: 'maven'
def artifactId = 'common'def groupId = \"com.baoliyota.lib\"def version = '1.0.0'uploadArchives { repositories { mavenDeployer {// snapshotRepository(url: \"http://172.16.55.160:8081/repository/maven-snapshot/\
会在项目同级目录生成android/..
需要引入的项目也需要在同级目录
其他项目使用
项目
build.gradle
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files }}allprojects { repositories { def devRoot = System.getenv(\"BY_DEV_ROOT\") if (devRoot == null || \"\".equals(devRoot)) { devRoot = file(\"./../../..\").toString() } if (file(devRoot).isDirectory()) { maven { url \"file://${devRoot}/android/distribute/libs/\" } } jcenter() }}task clean(type: Delete) { delete rootProject.buildDir}
app
repositories { def devRoot = System.getenv(\"BY_DEV_ROOT\") if (devRoot == null || \"\".equals(devRoot)) { devRoot = file(\"./../../..\").toString() } if (file(devRoot).isDirectory()) { maven { url \"file://${devRoot}/android/distribute/libs/\" } } }
compile 'com.baoliyota.lib:common:1.0.0@aar'
compile 'com.coolyota.lib:analysis:1.0.0@aar'
上传到服务器
upload.gradle
apply plugin: 'maven'task androidJavadocs(type: Javadoc) { source = android.sourceSets.main.java.srcDirs classpath += project.files(android.getBootClasspath().join(File.pathSeparator))}task androidSourcesJar(type: Jar) { classifier = 'sources' from android.sourceSets.main.java.srcDirs //生成在build/libs/目录下}artifacts { archives androidSourcesJar}//任务名uploadArchives { repositories { mavenDeployer { //这里的url是nexus中maven-releases的路径,可以点击copy按钮查看复制 repository(url: \"http://localhost:8081/repository/maven-releases/\") { // nexus账号的用户名和密码,我这里没用默认的admin authentication(userName: \"jcking\
指定output输出路径
根据buildType不同输出文件
android.applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile println(\"outputFile = \" + outputFile) if (outputFile != null && outputFile.name.endsWith('.apk')) { def fileName if (variant.buildType.name.equals('release')) { fileName = \"CY_Log_Reporter_user.apk\" } else if (variant.buildType.name.equals('debug')) { fileName = \"CY_Log_Reporter.apk\
android.applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile println(\"outputFile = \" + outputFile) if (outputFile != null && outputFile.name.endsWith('.apk')) { def fileName if (variant.buildType.name == 'release') { fileName = \"CY_Log_Reporter_user.apk\" } else if (variant.buildType.name == 'debug') { fileName = \"CY_Log_Reporter.apk\
android.applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile println(\"outputFile = \" + outputFile) if (outputFile != null && outputFile.name.endsWith('app-debug.apk')) { // 输出apk名称为CY_Log_Reporter_v1.0_2015-01-15_coolyota.apk def fileName = \"CY_Log_Reporter.apk\"// def fileName = \"CY_Log_Reporter_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk\" output.outputFile = new File(outputFile.parent + \"/../../../\
android.applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && (outputFile.name.endsWith('yotaDevice-debug.apk') || outputFile.name.endsWith('app-yotaDevice-release.apk'))) { //这里修改apk文件名 yotaDevice-debug def fileName = \"CY_BLauncher.apk\
生成SourceJar
task androidSourcesJar(type: Jar) { classifier = 'sources'// println(\"classifier = \" + classifier) from android.sourceSets.main.java.srcDirs //生成在build/libs/目录下}
右方Gradle-当前的moudle-Task-Other-androidSourcesJar 右键Run
生成JavaDoc
Your Moudle的build->outputs->docs->javadoc中找到文档了
右方Gradle-当前的moudle-Task-Other-androidJavadocs 右键Run
方法常量
def releaseTime() { return new Date().format(\"yyyy-MM-dd\
打印
println()
定义常量
def fileName
依赖包
谷歌
compile 'com.android.support:appcompat-v7:25.3.1'compile 'com.android.support.constraint:constraint-layout:1.0.2'compile 'com.android.support:design:25.1.0' compile 'com.android.support:support-v4:25.3.1' compile 'com.android.support:preference-v14:25.3.1'
第三方
LeakCanary
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.2' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.2'
底部tab
compile 'com.shizhefei:ViewPagerIndicator:1.1.6'由于用到了v4和recyclerview所以也要导入他们compile 'com.android.support:support-v4:23.4.0'compile 'com.android.support:recyclerview-v7:23.4.0'
混淆
mapping
路径
\\\\172.16.7.69\\temp\\BLauncherReleaseMapping
配置
签名
local.properties
本地Maven
类库端配置
使用端配置
版本兼容
com.android.tools.build:gradle:3.2.1
distributions/gradle-4.6-all.zip
com.google.protobuf:protoc:3.0.0-alpha-3 15/05
4.10-all 18/08Aug/27
4.10.1-all 18/09Sep/
distributions/gradle-5.1.1-all.zip
gradle:3.1.2
buildTools:27.0.3以上
gradle-4.4-all 以上
gradle:3.5.2
gradle-5.4.1-all.zip
6.0-all
kotlin 1.3.50
ext.kotlin_version = \"1.3.50\"
//手动添加以下两行 classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\" classpath \"org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version\"
EditText
textColorHighlight
如果不需要改变小水滴的图片,只是希望改变小水滴的颜色,那么只需要改变android:colorControlActivated的颜色值即可亲测无效
默认使用主题色中的colorAccent
textSelectHandle(选择文本的小水滴)
android:textSelectHandle 中间的选择器图标android:textSelectHandleLeft 左边的选择器图标android:textSelectHandleRight 右边的选择器图标
android:textSelectHandle=\"@color/blue_cursor_color\"
设置颜色变成空白
android:textColorHighlight
文字选中背景
android:textCursorDrawable=\"@drawable/cursor_color\"
drawable/cursor_color
点击全选
输入限制
不可编辑状态
监听事件
小数点2位
ListView
默认选择的位置
长按事件
在ScrlloView中
PinnedHeaderListView
PinnedHeaderExpandableListView
下拉刷新
安卓无ActionBar
加下划线
半圆背景
粗体
多行省略
字体颜色区分
跑马灯
按下改变文字颜色
selectordrawable/bg_button_text_color.xml
android:textColor=\"@drawable/bg_button_text_color\"
其他控件及效果
弹窗
DialogFragment
showEditDialog();
class
listener
CustomDialog
GridView
GridView 元素间距设定
选择(选中)控件
RadioGroup
RadioButton
XML
Selector
Java
Spinner
CheckBox
选中事件
ScrollView
焦点移动最顶端
系统控件
NavigationBar和StatusBar
设置颜色
getWindow().setNavigationBarColor(Color.BLUE);
0 条评论
回复 删除
下一页