Android 知识小结

498 阅读22分钟

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

juejin.cn/post/684490…

  • 布局

    • LinearLayout

    • RelativeLayout

    • FrameLayout

    • ConstraintLayout

      • www.jianshu.com/p/17ec9bd6c…

        • 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 方法展示
    • 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()

ContentProvider

  • 访问其他程序的数据

    • getContentResolver() 封装了 insert update delete query 方法 传入 uri uri其格式一般为 Uri.parse("content://com/example.app.provider/table1")
      传入的其他参数 列名、指定where约束条件、where占位符、结果排序

查询时 得到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平台库
  1. 使用标准 JNI 函数来替代使用 libandroid_runtime.so 中的 getJavaVM 和 getJNIEnv
  2. 使用公开 alternative __system_property_get 来替代使用 libcutils.so 中的 property_get 符号
  3. 使用应用本地版本来替代使用 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