android
UI界面
控件与布局
-
控件
-
TextView
- setTypeface(Typeface.createFromAsset(getContext().getAssets(),"SourceHanSerifCN-Heavy.otf"));
-
Button
- btn.setEnabled(false); ((GradientDrawable) btn.getBackground()).setColor(getResources().getColor(R.color.grey_300));
-
EditText
- inputType="textMultiLine"
-
ImageView
-
ProgressBar
-
AlertDialog
-
ListView
- 在getview中将convertView 缓存 如果等于空则加载布局,不为空就重用,提高了运行效率,在滚动的时候表现出更好的性能
- 新增viewholder内部类 对子控件进行缓存 当convertView 为空创建一个viewholder对象 并将控件实例放入 当不为空时调用view的gettag方法取出 然后获取当前的条目 如果不等于空给子控件赋值
-
RecyclerView
- adapter重写3个方法 onCreateViewHolder() 用于创建viewHolder() 实例并把布局传入返回实例 onBandViewHolder() 对子项的数据进行赋值 getItenCount() 告诉recyclerview 有多少条目
- 设置布局管理器layoutmanager gridlayoutmanager 网格布局 staggeredgridlayoutmanager 瀑布流
- github.com/jdsjlzx/LRe…
- 缓存 Recycler缓存ViewHolder对象有4个等级,优先级从高到底依次为:
-
一级缓存ArrayList mAttachedScrap 缓存屏幕中可见范围的ViewHolder
二级缓存ArrayList mCachedViews 缓存滑动时即将与RecyclerView分离的ViewHolder,按子View的position或id缓存,默认最多存放2个
三级缓存ViewCacheExtension mViewCacheExtension 开发者自行实现的缓存
四级缓存RecycledViewPool mRecyclerPool ViewHolder缓存池,本质上是一个SparseArray,其中key是ViewType(int类型),value存放的是 ArrayList< ViewHolder>,默认每个ArrayList中最多存放5个ViewHolder
-
布局
-
LinearLayout
-
RelativeLayout
-
FrameLayout
-
ConstraintLayout
-
- constraintLeft_toRightOf属性用 constrain 修饰
- 角度定位 app:layout_constraintCircle="@+id/TextView1" app:layout_constraintCircleAngle="120"(角度) app:layout_constraintCircleRadius="150dp"(距离) 以其他空间为中心 设置空间中心与其角度和距离
- 边距 先声明 app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" 约束位置才能使margin生效
-
-
goneMargin主要用于约束的控件可见性被设置为gone的时候使用的margin值 - 居中和偏移 app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" 偏移 layout_constraintHorizontal_bias 水平偏移 layout_constraintVertical_bias 垂直偏移 - 尺寸约束 android:minWidth 最小的宽度 android:minHeight 最小的高度 android:maxWidth 最大的宽度 android:maxHeight 最大的高度
官方不推荐在ConstraintLayout中使用match_parent,可以设置 0dp (MATCH_CONSTRAINT) 配合约束代替match_parent
当宽或高至少有一个尺寸被设置为0dp时,可以通过属性layout_constraintDimensionRatio设置宽高比 - 链 layout_constraintHorizontal_chainStyle来改变整条链的样式。chains提供了3种样式,分别是: CHAIN_SPREAD —— 展开元素 (默认); CHAIN_SPREAD_INSIDE —— 展开元素,但链的两端贴近parent; CHAIN_PACKED —— 链的元素将被打包在一起。
我们把宽度都设为0dp,这个时候可以在每个TextView中设置横向权重layout_constraintHorizontal_weight(constraintVertical为纵向)来创建一个权重链 - Optimizer 当我们使用 MATCH_CONSTRAINT 时,ConstraintLayout 将对控件进行 2 次测量,ConstraintLayout在1.1中可以通过设置 layout_optimizationLevel 进行优化,可设置的值有: none:无优化 standard:仅优化直接约束和屏障约束(默认) direct:优化直接约束 barrier:优化屏障约束 chain:优化链约束 dimensions:优化尺寸测量
Barrier 可以在多个控件的一侧建立一个屏障 app:barrierDirection为屏障所在的位置,可设置的值有:bottom、end、left、right、start、top app:constraint_referenced_ids为屏障引用的控件,可设置多个(用“,”隔开)
Group 可以把多个控件归为一组,方便隐藏或显示一组控件
Placeholder 指的是占位符。在Placeholder中可使用setContent()设置另一个控件的id,使这个控件移动到占位符的位置
Guideline Guildline像辅助线一样,在预览的时候帮助你完成布局(不会显示在界面上)。 Guildline的主要属性: android:orientation 垂直vertical,水平horizontal layout_constraintGuide_begin 开始位置 layout_constraintGuide_end 结束位置 layout_constraintGuide_percent 距离顶部的百分比(orientation = horizontal时则为距离左边)
自定义控件
-
引入布局
- include
-
继承View
- 重写构造方法设置xml视图
- 测量 :onMeasure(),用来控制自定义View的宽高
- 位置:onLayout(),在继承ViewGroup的时候需要重写该方法,用来控制子View摆放的位置。
- 绘图:onDraw(),自定义View的主要方法,需要重载或重写该方法来绘制所需要的控件。
-
动画
- 帧动画:将一张张单独的图片连贯的进行播放
- 补间动画: alpha(淡入淡出),translate(位移),scale(缩放大小),rotate(旋转) 一般会采用xml 文件的形式
- 属性动画:ObjectAnimator 这个类,这个类继承自ValueAnimator,使用这个类可以对任意对象的任意属性进行动画操作
Fragment
-
基本用法
- 获取fragmentManager 调用beginTransaction() 调用 replace() 和 commit()
-
Fragment和Activity通信
- activity : supportFragmentManager.findFragmentById(R.id.fragment) as LeftFragment
- fragment: getActivity
-
生命周期
- onAttach() 建立与activity关联 onCreateView() fragment创建视图 onActivityCreated() 确保Activity 创建完毕 onDestoryView 与fragment 关联视图移除时 onDetach 解除与activity关联
-
动态添加布局
- 创建 layout-large/activity_main 限定符 large 默认给大屏幕设备的资源
- layout-sw600dp 屏幕宽度大于等于600dp 加载这个文件夹中的布局
Material Design android 5.0
-
标题栏Toolbar
- 首先activity 主题设置NoActionBar colorPrimaryDark 状态栏颜色 colorPrimary 顶部栏颜色 textColorPrimary 顶部栏文字颜色 windowBackground 背景色 navigationBarColor 底部栏颜色 colorAccent 按钮选中颜色
- setSupportActionBar(toolbar) 设置给activity 在清单文件设置activity 的 label 决定toolbar 的问题在 Menu 文件夹下 编辑Menu item 通过acitivity 的onCreateOptionsMenu 设置给toolbar 后在 onOptionsItemSelected 设置点击方法
-
滑动菜单
-
DrawerLayout
- 滑动菜单 允许放入2个子控件 第一个是主屏幕显示的内容 第二个是滑动菜单中显示
第二个子控件layout_gravity 声明滑动菜单的左右 - getSupportActionBar().setDIsplayHomeAsUpEnabled(true) 显示导航按钮 setHomeAsUpIndicator() 设置图标 在onOptionsItemSelected 中判断id是 R.id.home 调用openDrawer 方法展示
- 滑动菜单 允许放入2个子控件 第一个是主屏幕显示的内容 第二个是滑动菜单中显示
-
NavigationView
- xml menu 属性 设置菜单 headerLayout 设置头部布局 在activity中setNavigationItemSelectedListerer{} 设置选中监听
-
-
悬浮按钮和可交互提示
-
FloatingActionButton
- 悬浮按钮 elevation 悬浮高度
-
Snackbar
- Snackbar.make(view,"xx",short).setAction().show 底部提示栏
-
CoordinatorLayout
- 加强版FrameLayout 可监听Snackbar 的弹出事件 会将floatbtn 向上偏移
-
-
卡片式布局
-
MaterialCardView
- cardCornerRadius 指定圆角弧度 elevation 指定高度
-
AppBarLayout
- 使用CoordinatorLayout布局时 appbarlayout包裹Toolbar 并将下方布局 layout_behavior 属性 设置为@string/appbar_scrolling_view_behavior 可修改toolbar隐藏的Bug 还可在toolbar 中设置 layout_scrollFlags 为scroll|enterAlways|snap 表示 recyclerview向上滚 toolbar隐藏 向下滚显示 并会根据距离自动选择隐藏显示
-
-
下拉刷新
-
SwipeRefreshLayout
- 包裹RecyclerView setColorSchemeResources 指定进度条颜色 setOnRefreshListener 下拉刷新监听
-
-
可折叠标题栏
-
CollapsingToolbarLayout
- 只能作为appBarLayout 直接子布局 appBarLyaout 又必须是CoordinatorLayout 的子布局
- layout_collapseMode 折叠模式 pin 为始终不变 parallax 表示错位偏移
- fitsSystemWindows 属性 设置为true 能让控件与系统状态栏融合 前提是将acitivity 主题中statusBarColor 设置为 color/transparent
-
深色主题
- android 10.0中引入 创建 values-v29 目录下 创建styles.xml 将apptheme 添加 forceDarkAllowed 为true
- 第二种方式 将xml中的 parent 改为 DayNight.NoActionBar 创建values-night 目录colors.xml 设置 Primary primaryDark Accent 的颜色值 activity的xml文件中 背景色设为 ?android:attr/colorBackground textview 设置为textcolorPrimary
- context.resources.configuration.uimode android Configuration.UI_MODE_NIGHT_MASK 获取是否是夜间模式 根据结果执行代码
多媒体
通知
-
通知渠道
- android 8.0 引入 每条通知都属于对应的渠道,每个应用程序都可以创建渠道,用户控制是否响铃等 getSystemService(Context.NOTIFICATION_SERVICE) 获取 NotificationManager 对象 manager.createNotificationChannel( NotificationChannel(channelId,channelName,importance) ) 创建一个通知渠道传入的是渠道id 渠道名称和重要等级
-
基本用法
- NotificationCompat.Builder(context,channelId).build() 兼容API 再设置title text icon 最后 调用notify() 传入id 和通知 调用setContentIntent() 传入PendingIntent 点击通知会执行 设置setAutoChancel() 点击通知消失 或者在新界面调用manager.cancel() 传入id
-
进阶技巧
- setStyle() 传入长文字 BigTextStyle 大图片 BigPIctureStyle 高等级通知 显示横幅和图片
选取图片
-
调用摄像头拍照
- 创建文件时 android 10.0 开始公有的sdk目录 不再被允许应用程序直接访问 需使用作用域存储 android 7.0 开始 直接使用本地真实Uri 被认为不安全 会抛出FileUriExceotin 异常,FileProvider 是一种特殊的contentProvider 类似的机制对数据进行保护 可以选择性的封装过的Uri 共享给外部 提高应用安全性 版本小于7.0就调用Uri的 fromFile() 否则调用 FileProvider 的getUriForFile() 将file转为Uri
Intent("android.media.action.IMAGE_CAPTURE") intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri) 打开相机 设置图片保存路径
FileProvider 需在清单文件中注册 authorities 属性需和getUriForFile 第二个参数一致 meta-data 制定uri 的共享路径 并引入了@xml/file_paths 资源 文件中 external-path 指定uri共享 name 随便写 path 填写具体的共享路径
-
从相册中选取
- Intent(Intent.ACTION_OPEN_DOCUMENT) intent.addCategory(Intent.CATEGORY_OPENABLE) intent.type="image/*"
获取图片 bitmap=BitmapFactory.decodeStream(contentResolver.openInputStream(imageuri)) 或者 Uri data1 = data.getData(); img.setImageURI(data1); 或者 img.setImageURI(Uri.fromFile(new File(paths.get(0))));
播放多媒体文件
-
播放音频
- MediaPlayer setDataSource -> prepare -> start
-
播放视频
- VideoView setVideoPath 传入 Uri 后 start
录制音频
架构设计
MVP
- MVP是为XML配合Activity或Fragment为V(视图),同时抽象出接口,界面相关业务抽离出来的P(Presenter)同时通过视图接口来更新UI,数据实体为M(模型)。
MVVM
- Model 是数据模型 View是界面展示 ViewModel 连接数据模型和界面展示的桥梁 从而实现业务逻辑和界面展示分离
Jetpack 开发组件工具集 前提是编程语言使用kotlin 更适用于MVVM架构
-
ViewModel
- 用于存放于界面相关的数据,减少activity的工作,旋转屏幕不销毁,activity退出销毁
- ViewModelProviders.of(this).get(MainViewModel::class.java)
-
Lifecycles
- 让任何一个类感知activity生命周期 lifecycleOwner.lifecycle.addObserver(MyObserver()) lifecycle.currentState 是当前activity已经执行了什么生命周期方法
-
LiveData
- 响应式编程组件 包含任意数据 发生变化时通知观察者 绝大多数与viewModel 一起使用
- 用 LiveData< T > 修饰数据 将get()= private val 变量=MutableLIveData() 其内部又有get set post 三个方法
- Transformations.map(data) {} 可将数据转换为其他类型 参数是原始数据和转换函数 Transformations.switchmap(data) {} 如果viewmodel中某个livedata 是通过调用另外方法获取的 不可观察时 用这个方法转换为可观察对象 当某个获取数据的方法没有参数 就让value = value
-
Room
- 用面向对象的思想操纵数据库 Entity 用于封装实际数据的实体类 类在库中有表 表中列根据字段自动生成 Dao 对数据库操作封装 直接访问Dao Database 定义库关键信息 版本号 包含实体类 和访问实例 Entity用注解标注实体类 Dao是标注接口 并标注增删改查方法 Database标注抽象类
- 在开发测试阶段 可设置allowMainThreadQueries() 使数据库在主线程运行 fallbackToDestrectiveMigration() 只要数据库升级 就会销毁当前并新建
- 数据库升级时addMigrations 写一个类继承 Migrations 传入1,2 和 函数体 代表1升2时执行函数内容 增加列 用alter 修改表结构
-
WorkManager
- 后台处理定时任务的工具 1.定义后台任务实现任务逻辑 类继承worker 重写 doWork 方法 2.配置运行任务的约束条件 并构建请求 OneTimeWorkRequest.build 是一次 PeriodicWorkRequest 第二个参数是 间隔时间 要求不短于15分钟 3.将任务传入 workManager 的 enqueue() 方法中 WorkManager.getInstance.enqueue(request)
- setInitialDelay 可设置延迟执行时间 addTag 添加标签 cancelWorkById 根据标签取消 setBackoffCriterid 重新执行任务 getWorkInfoByIdLiveData 配合 observe 可监听执行结果 beginWith 配合 then 可实现链式任务
主要组件
Activity
-
基本用法
- 在Acitivity中使用menu 生成顶部栏最右边三个点 可在onCreateOptionsMenu 中声明布局 并在 onOptionsItemSelected 中 实现点击方法
-
Acitivity之间跳转
- 显示Intent直接声明跳转目标
- 隐式Intent 在清单文件声明 intent-filter action category 一致才可跳转,还可跳转其他应用
- 返回给上个acitivty 数据 在第二个activity 中调用setResult 放发传入 requestcode 和intent
-
生命周期
- 7个回调方法onCreate、onStart、onResume、onPause、onStop、onDestory、onRestart
- activity 保存数据 onSaveInstanceState 方法 获取在 onCreate 中通过bundle 获取
-
启动模式
- standard 默认 添加后位于栈顶
- singleTop 栈顶复用 相同的时候不新建
- singleTask 如果实例存在 将其上activity 移出栈
- singleInstance 启用一个新栈管理这个activity
-
最佳实践
- 可在baseActivity 中通过simpleName 获取当前类名
- 可在baseActivity 声明activity集合 关闭所有 并退出程序
- 启动activity 最佳写法写在目标 activity 中 通过companion object 修饰为静态的 直接调用
-
底部栏和顶部栏的位置
- ViewGroup rootView = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content); if (hasNavBar(this)){ rootView.setPadding(0, getStatusBarHeight(), 0, getNavigationBarHeight(this)); }else { rootView.setPadding(0, getStatusBarHeight(), 0, 0); } 在onCreate 中 super.onCreate 上加入这个方法 如果有底部栏 设置padd 为底部栏高度 还可通过这个方法 讲距离top的padd设为0 将状态栏设置透明后 将界面深入状态栏
BroadcastReceiver
-
接收广播
-
静态注册
-
在AndroidManifest.xml中注册
- android8.0以后所有隐式广播都不允许使用静态注册接收 发自定义广播时 intent.setPackage(packageName) 使广播变为显示广播
-
-
动态注册
- 在代码中注册
-
-
发送广播
-
标准广播
- sendBroadcast
-
有序广播
- sendOrderedBroadcast(intent,null) 第二个参数是与权限相关的字符串 并在注册广播时声明 priority
截断广播调用abortBroadcast()
- sendOrderedBroadcast(intent,null) 第二个参数是与权限相关的字符串 并在注册广播时声明 priority
-
ContentProvider
-
访问其他程序的数据
- getContentResolver() 封装了 insert update delete query 方法 传入 uri
uri其格式一般为 Uri.parse("content://com/example.app.provider/table1")
传入的其他参数 列名、指定where约束条件、where占位符、结果排序
- getContentResolver() 封装了 insert update delete query 方法 传入 uri
uri其格式一般为 Uri.parse("content://com/example.app.provider/table1")
查询时 得到cursor 对象 判断moveToFirst 调用 cursor.getX(cursor.getColumnIndex(X) ) 获取值 最后 cursor.close
增删改 都是通过 contentValuesOf() 获取参数和uri一起传入方法 和数据库操作一样
-
提供数据访问的接口
- 写类继承ContentProvider 重写方法 uri 末位是 * 为任意表 # 为任意行
Service
-
写一个类继承Service 重写 onBind onCreate onStartCommand onDestory 方法 onStartCommand 在启动时候调用 需在清单文件中注册
-
启用和停止Service
- startSevice stopService 从android8.0开始 service 进入后台随时可能被系统回收
-
Service和Activity通信
- 写一个类继承Binder 通过 onBind 返回 bindService unbindService 其中类的onServiceConnected 在与activity 绑定成功时调用 onServiceDisconnected 在service 崩溃或被杀死调用
-
生命周期
- onCreate-> onStartCommand 或者 onBind 最后 onDestory
-
前台Service
- 有一个正在运行的图标和状态栏提示,在onCreate 方法中创建一个渠道通知 最后startForeground 启用 从android 9.0起 前台service 需申请权限
-
IntentService
- 异步的会自己停止的Service 类继承IntentService 重写 onHandleIntent 方法 可在方法中处理耗时逻辑 运行完毕后会自动停止
Application
- 全局获取Context 写一个类继承 Application 并在清单文件 application name 中声明
Intent
-
显示Intent
-
隐式Intent
-
传递数据
-
传递基本数据
-
传递对象
- 实现 Serializable 接口 将对象设置可存储和传输的状态
- 实现 Parcelable 接口 重写 describeContents 和 writeToParcel 两个方法 也可直接 @Parcelize 注解实体类
-
多线程
-
新建类继承Thread 重写run方法 .start 启动
-
新建类实现Runnable 接口重写run方法 Thread(myrunnable).start启动
-
异步消息处理
- Message线程之间传递的消息,可携带少量信息
- Handler消息处理者,用于发送和处理消息,发送sendMessage、post方法 处理消息用 handleMessage 方法 子线程发出通知 主线程处理
- MessageQueue 消息队列 存放handler 发送的消息 每个线程只有一个消息队列
- Looper 每个线程中MessageQueue的管家 也只有一个 调用Looper的loop方法后 就会循环 消息队列 有消息就取出
- AsyncTask 三个参数 params 、progress 进度单位、Result 返回值类型 onPreExcure 在后台任务执行前调用 用于界面初始化 显示进度条对话框等 doInBackground(Params) 方法中所有代码在子线程运行 处理耗时任务 onProgressUpdate(Progress) 可对ui操作 利用参数更新 onPostExecute(Result) 提醒任务执行结果 关闭进度条等 AsyncTask.execute() 启动
线程池
- 好处 1:对多个线程进行统一地管理,避免资源竞争中出现的问题。 2:(重点):对线程进行复用,线程在执行完任务后不会立刻销毁,而会等待另外的任务,这样就不会频繁地创建、销毁线程和调用GC。 3:JAVA提供了一套完整的ExecutorService线程池创建的api,可创建多种功能不一的线程池,使用起来很方便。
- 1:ThreadPoolExecutor 创建基本线程池 参数 corePoolSize: 该线程池中核心线程的数量。maximumPoolSize:该线程池中最大线程数量。keepAliveTime:非核心线程空闲时要等待下一个任务到来的时间 unit:上面时间属性的单位 workQueue:任务队列 threadFactory:线程工厂,可用于设置线程名字等等,一般无须设置该参数。 适用:执行很多短期异步的小程序或者负载较轻的服务器
- 2:FixedThreadPool (可重用固定线程数) 特点:参数为核心线程数,只有核心线程,无非核心线程,并且阻塞队列无界。 适用:执行长期的任务,性能好很多
- 3:CachedThreadPool (按需创建) 特点:没有核心线程,只有非核心线程,并且每个非核心线程空闲等待的时间为60s,采用SynchronousQueue队列。
- 4:SingleThreadPool(单个核线的fixed) 适用:一个任务一个任务执行的场景
- 5:ScheduledThreadPool(定时延时执行) 适用:周期性执行任务的场景
- 6:自定义的PriorityThreadPool(队列中有优先级比较的线程池)
- 1.shutDown() 关闭线程池,不影响已经提交的任务 2.shutDownNow() 关闭线程池,并尝试去终止正在执行的线程 3.allowCoreThreadTimeOut(boolean value) 允许核心线程闲置超时时被回收 4.submit 一般情况下我们使用execute来提交任务,但是有时候可能也会用到submit,使用submit的好处是submit有返回值。 5.beforeExecute() - 任务执行前执行的方法 6.afterExecute() -任务执行结束后执行的方法 7.terminated() -线程池关闭后执行的方法
数据存储
文件存储
- 写入文件 openfileoutput() 第一个参数是文件名,第二个参数是操作模式 覆盖或者追加 将对象传入BufferedWrite(OutputStreamWriter(output)) writer,use{it.write(inputText)} 写入 保存在包名下files 目录下
- 读取文件openFileInput() 传入文件名会到files目录下加载文件 BufferedReader(InputStreamReader(input)) reader.use{read.forEachLine{content.append(it)}} 打印声明的content 就可获取内容
SharedPreferences存储
-
Context 中的 getSharedPreferences 方法 存在 /包名/shared_prefs 目录下
-
Activity 中的getPreferences 自动将activity类名 作为sp文件名 其他activity 获取不到
-
保存 getSharedPreferences.edit() editor.putXX.apply()
-
读取 getSharedPreferences.getXXX
SQLite存储
-
SQLiteDatabase
- 创建类继承SQLiteOpenHelper 在onCreate 中exeSQL() 执行sql 语句 获取help对象后调用 writableDatabase
- 读取db文件插件 Database Navigator
- insert(表名,null, ContentValues) put 数据 update(表名, ContentValues,约束,约束) 约束更新某一行或某几行的数据 delete(表名, ContentValues,约束) query(表名,列,约束,约束,group by操作,过滤,排序) 先获取cursor 对象 判断moveToFirst 调用 cursor.getX(cursor.getColumnIndex(X) ) 获取值 最后 cursor.close
- 除系统封装的增删改查也可直接使用SQL操作数据库 db.execSQL 和 db.rawQuery
- db.beginTransaction() 开启事务 db.setTransactionSuccessful() 事务已经执行成功 db.endTransaction() 结束事务 开启后在try catch 代码块中执行 增删改查 调用执行成功 finally 中结束事务
-
Room
网络通信
发起请求
-
HttpURLConnection
- HttpClient 在6.0中被移除 conection=URL("www.baidu.com").openConnection as HttpURLConnection conection.connectTimeout =8000 conection.readTimeout=8000 val input=conection.inputStream val reader=BufferedReader(InputStreamReader(input)) reader.use{ reader.forEachLine{ 遍历内容 } } 以上代码在子线程 遍历内容需切换主线程
-
OkHttp
- val client=OkhttpClient() var request=Request.Builder().url("baidu").build var response=client.newCall(request).execute
解析响应
-
XML
-
Pull解析
- factory=XmlPullParserFactory.newInstance() xmlPullParser=factory.newPullParser() xmlPullParser.setInput(StringReader(xmlData)) eventType=xmlPullParser.eventType
-
SAX解析
- 创建一个类继承DefaultHandler 并重写5个方法 startDocument 开始解析时 startElement 解析某个节点时调用 characters 获取节点中内容时调用 endElement 解析完成某个节点 endDocument 解析完成调用 解析时 factory=SAXParserFactory.newInstance() xmlReader=factory.newSAXParser.getXMLReader xmlReader.contentHandler=DefaultHandler 的实现类 xmlReader.parse(InputSource(StringReader(xmldata)))
-
-
JSON
-
JSONObject
- jsonArray=JSONArray(jsondata) for(i in 0 until json.length()){ jsonObject= jsonArray.getJSONObject(i) value=jsonObject.getString(key) }
-
Gson
- Gson.fromJson(jsondata,Person::class.java)
- 解析json数组 val typeOf=object: TypeToken<List>(){}.type val Persionlist=gson.fromJson<List> (jsondata,typeOf)
-
Retrofit
- 可设置baseUrl,可对接口进行分类
- 声明接口 在接口中使用注解@get 标注方法 get中的参数就是相对路径 方法的返回值必须声明Retrofit 中的Call类型并通过泛型指定服务器相应数据换成什么对象
- val retrofit=Retrofit.builder().baseurl("").addConverterFactory(GsonConverterFactory.create()).build appserver=retrefit.create(appservice::class.java) appservice.getAppData().enqueue(Callback)
- 复杂接口地址 在@GET 注解中添加 {} 占位符 并在方法中增加参数 可实现拼接地址 get多个参数 可在方法中使用 @Query 拼接参数 Post 请求参数在方法中 @Body 请求头中有参数 可在@GET 上添加 @Headers() 这是静态的声明,如果是动态的header 需在方法参数中实现
进程间通信
版本特性
5.0
- 由Dalvik虚拟机改为ART运行环境
- Material Design设计风格 和控件
6.0
-
运行时权限
- 危险权限共11组30个相机、定位、打电话、发信息等
-
取消支持 Apache HTTP 就是httpClient
-
低电耗模式 和 待机(休眠)模式 后台常驻服务在息屏状态下无法接受网络请求! 忽略 wake locks.不执行 Wi-Fi 扫描.不允许运行 JobScheduler. 可通过代码 设置低电耗模式白名单
-
Android 移除了对设备本地硬件标识符的编程访问权 WifiInfo.getMacAddress() 方法和 BluetoothAdapter.getAddress() 方法现在会返回常量值 02:00:00:00:00:00 要通过蓝牙和 WLAN 扫描访问附近外部设备的硬件标识符,您的应用必须拥有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 权限
-
AudioManager 类直接设置音量或将特定音频流静音
-
文本选择 用户在应用中选择文字后,你现在可以显示一个浮动工具栏(floating toolbar)startActionMode OnGetContentRect()方法,提供内容Rect对象 在view中的位置 作为唯一的元素不再有效时invalidateContentRect()
-
移除了全局书签的支持 getAllBookmarks saveBookmark 和权限均被移除
-
相机服务变更
7.0
- 低电耗模式 会对闹铃、GPS 和 Wi-Fi 扫描 产生限制. 可参考Optimizing for Doze and App Standby 使用GCM来发送和接受消息
- 后台优化 Android N 删除了三项隐式广播,隐式广播会在后台频繁启动已注册侦听这些广播的应用。 删除这些广播可以显著提升设备性能和用户体验.
侦听网络变化的主线程广播改为: CONNECTIVITY_CHANGE。 对所有应用都无法 发送和接受 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO .
可以使用JobScheduler API ,更多参考后台优化
- 系统权限更改 App私有目录被限制访问 私有文件的文件权限不应再由所有者放宽,为使用MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE而进行的此类尝试将触发SecurityException,会导致App崩溃的。
- 应用间共享文件 Android N 上 安装Apk时报错:android.os.FileUriExposedException: 在清单文件中
- 多窗口支持(分屏显示)
- NDK平台库
- 使用标准 JNI 函数来替代使用 libandroid_runtime.so 中的 getJavaVM 和 getJNIEnv
- 使用公开 alternative __system_property_get 来替代使用 libcutils.so 中的 property_get 符号
- 使用应用本地版本来替代使用 libcrypto.so 中的 SSL_ctrl 符号
- 注解保留 在注解可见性被忽略时修复错误 VISIBILITY_BUILD:仅应编译时可见。 VISIBILITY_SYSTEM:运行时应可见,
- 多语言区域支持,更多语言,新增的表情符号
8.0
-
通知渠道
- 创建 NotificationChannel 对象,并设置应用内唯一的通知 ID。 配置通知渠道的属性,比如提示声音等。 在 NotificationManager 中注册通知渠道对象。
-
启动图标
- 通过定义两张图层(前景与背景)你可以制定你的桌面图标外观,你必须提供没有形状和阴影的 PNG 格式图象作为图层。
-
画中画模式
- Activity 处于 PIP 模式时 ,其实它是出在暂停状态,但其内容会继续展示。Activity.enterPictureInPictureMode(PictureInPictureArgs args):将Activity置于 PIP 模式之下。 Activity.setPictureInPictureArgs():用于更新 Activity 在 PIP 模式下的设置。如果 Activity 正处于 PIP 模式之下,那么更改的属性将立即生效。
-
固定快捷方式和小部件 — Pinning shortcuts
9.0
-
系统默认只允许Https类型的网络请求,http认为有安全隐患,需创建xml目录 network_config.xml文件 进行network-security-config 设置 并需要在配置文件application 下声明 才允许以明文方式在网络传输数据
-
室内WIFI定位
-
“刘海”屏幕支持
- 借助最新的提供的DisplayCutout类,开发者可以找到非功能区域的位置和形状,而非功能区域是不应显示功能的;使用getDisplayCutout()就可以获取这个区域的详细信息
-
通知 增强体验 通道设置、广播以及免打扰
-
多相机支持和相机更新
- 应用处在后台时,不可访问麦克风、摄像头、传感器 如需使用,可以使用前台服务
- CameraManager.getCameraIdList()方法,检查每个可用摄像头
-
新的图片解码
- ImageDecoder类来代替BitmapFactory和BitmapFactory.Options类,可以通过API实现图片的加载、裁剪、圆角、包括Gif图等处理,对于Gif图(AnimatedImageDrawable)的处理会应用到每一帧
-
动画
- AnimatedImageDrawable类,用于绘制和显示 GIF 和 WebP 动画图像
-
HDR VP9视频,HEIF图像压缩和媒体API
-
安全增强
-
Android 备份加密
10.0
-
AndroidQ引入了大量更改和限制以增强对用户隐私的保护。
- 访问系统媒体文件 READ_MEDIA_IMAGES,READ_MEDIA_VIDEO,READ_MEDIA_AUDIO,申请方法同原来的存储权限。取消了读写文件权限 要访问其中其他应用的文件,必须允许用户使用系统的文件选择器应用来选择文件。
-
在外部存储设备中为每个应用提供了一个“隔离存储沙盒”
- 存储权限 谷歌官方推荐应用在沙盒内存储文件的地址为Context.getExternalFilesDir()下的文件夹。比如要存储一张图片,则应放在Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)中。
-
设备唯一标识符
- READ_PRIVILEGED_PHONE_STATE 签名权限 ((TelephonyManager) getActivity() .getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()
-
非 SDK 接口限制,被限制的接口的分类有较大变化。
11.0
底层源码
应用启动流程
RecyclerView
Glide
Retrofit
eventBus
XMind - Trial Version