美文网首页
Android 工作手记

Android 工作手记

作者: 小仙女喂得猪呀 | 来源:发表于2022-08-11 18:16 被阅读0次

    Mac vim命令行操作

      MAC 终端编辑完成后如何保存 如果是vi,则:Esc 退出编辑模式,输入以下命令: 
      :wq 保存后退出vi
      :wq! 则为强制储存后退出(常用) 
      :w 保存但不退出(常用) 
      :w! 若文件属性为『只读』时,强制写入该档案 
      :q 离开 vi (常用) 
      :q! 若曾修改过档案,又不想储存,使用 ! 为强制离开不储存档案。
      :e! 将档案还原到最原始的状态!
    
      配置环境变量:vim ~/.zshrc 按照里面模板去配置 source ~/.zshrc 保存
    

    flutter配置时报错(flutter not find)

    1,open ~/.bash_profile
        export PUB_HOSTED_URL=https://pub.flutter-io.cn
        export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
        export PATH=/Users/mac/flutter/bin:$PATH
    2.open ~/.zshrc 如果文件夹不存在 用vim命令创建文件夹并且和.bash_profile
    中内容保持一致保存退出后,再终端输入:source .bash_profile 更新配置
    

    android工作中碰到的些许问题

    1, Android studio 编译问题:finished with non-zero exit value 2
      问题:Error:Execution failed for task
      ':androidShopNC2014Moblie:transformClassesWithDexForDebug'.>
      com.android.build.api.transform.TransformException:
      com.android.ide.common.process.ProcessException:
      java.util.concurrent.ExecutionException:
      com.android.ide.common.process.ProcessException:
      org.gradle.process.internal.ExecException:
      Process 'command
      '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java''
      finished with non-zero exit value 2
    
      答案:android {
      defaultConfig {
      multiDexEnabled true
      }
      }
    
     2>.Android studio 编译问题:finished with non-zero exit value 1(由于导入的依赖出现重复造成的)
     问题:Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
     
      >
      com.[Android](http://lib.csdn.net/base/15).build.api.transform.TransformException:
      com.android.ide.common.process.ProcessException:
      org.gradle.process.internal.ExecException: Process 'command 'F:\Program Files
      (x86)\[Java](http://lib.csdn.net/base/17)\jdk1.8.0_31\bin\java.exe'' finished
      with non-zero exit value 1
     
      解决方案:这个是因为依赖包重复了
      (像v4和nineoldandroids),app中实现了对easeUI的依赖,但是app和easeUI都添加了对这个包的依赖。
      所以就报这个错误,修改之后再报,就clean,rebuild一下。
    
    3>.Android studio 编译问题:finished with non-zero exit value
      1(由于buildtools版本太高造成的)
     
      Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
      > com.android.ide.common.process.ProcessException:
      org.gradle.process.internal.ExecException:
      Process 'command
     '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java''
      finished with non-zero exit value 1
     
      错误原因: buildToolsVersion版本太高,我原来的 buildToolsVersion "24.0.0”
     需要jdk1.8,而我的是jdk1.7,所以一直报这个错,刚开始以为是v4包和V7包冲突,
     因为之前遇到这样的问题,而这次删除V4包之后依然报这个错,上stackoverflow搜了一下,
     把buildTools版本降下来就好了。
    
    4,执行 bash: ./gradlew: Permission denied
    解决方案: chmod +x gradlew
    执行./gradlew build --scan 命令查看编译问题 详细报错信息
    
    5.Manifest merger failed with multiple errors, see logs
     解决方案:./gradlew processDebugManifest --stacktrace
     
     查看编译错误: ./gradlew clean assembleDebug --stacktrace
    
    • 连接mumu模拟器: adb connect 127.0.0.1:5555

    • 依赖树 android studio查看第三方依赖树

    • mac打开环境变量配置: open -e .bash_profile 刷新环境变量配置: source .bash_profile

    • 生成ssh 如果本地有id_rsa.pub 先删除本地文件 之后命令行执行 ssh-keygen -t rsa -C
      "jiyajie@aspirecn.com",一直确定即可

    • Webview优化: 创建一个全局的webView 将web单独一个进程,用aidl进行通信

    • Activity 的 isDestroy 在被Activity调用之前就已经赋值
      所以只要是在onDestroy中处理的过程中isDestroy()返回一直未true

    • 获取应用签名信息
      JKS 密钥库使用专用格式。
      建议使用
      2(.keystore文件), keytool -list -v -alias migu -keystore
      /Users/jiyajie/mgsv4pad_new/mgsv4pad_playvideo/mgsv4pad/app/padkey.jks

    • Dart 语法筑基

    • charles 抓包工具配置和使用文档

    brew 安装scrcpy

    Mac安装scrcpy:

    1,brew install scrcpy

    2,安装过程比较缓慢 如果出现某一个包安装失败
    使用 brew install (具体的包名即可 不要带提示的版本号,否则依然找不到下载路径)
    这个过程非常漫长 如果有提示就一直brew install,终有一次会成功的
    这个过程我断断续续用了五六天时间来完成

    git基本操作

    git 拉取代码:
     
     执行: git fetch upstream
     
     把上游的远程代码合并到本地的 master分支
     
     git checkout master
     
     git merge upstream/master
     
     git commit –amend git  commit --amend
     相当于上次提交错误的信息被覆盖了,gitk图形化界面上看不到上次提交的信息,
     git log上也看不到之前的信息,而add 后再commit
     相当于重新加了一个信息。相当于打了个补丁
     
     如果你想保留刚才本地修改的代码,
     并把git服务器上的代码pull到本地(本地刚才修改的代码将会被暂时封存起来)
      git stash
      git pull origin master
      git fetch upstream
      git merge upstream/master
      git stash pop
     
     Git远程放弃修改之后,本地恢复到某一个节点
     git reset --soft a287041c0fd791412ff6351c705b036f04237a6e
     git push origin master --force
    

    部分adb命令操作

     12.adb 开启应用 adb shell am start -n cn.cmvideo.car.play/.SplashActivity(包名)
     adb shell getprop dalvik.vm.heapgrowthlimit
     单个应用可用最大内存主要对应的是这个值,它表示单个进程内存被限定在64m,
     即程序运行过程中实际只能使用64m内存,超出就会报OOM。(仅仅针对dalvik堆,不包括native堆)
     dalvik.vm.heapstartsize 表示分配的初始堆大小
     dalvik.vm.heapsize
     heapsize参数表示单个进程可用的最大内存,但如果存在heapgrowthlimit参数,
     则以heapgrowthlimit为准.heapsize表示不受控情况下的极限堆,
     表示单个虚拟机或单个进程可用的最大内存。而android上的应用是带有独立虚拟机的,
     也就是每开一个应用就会打开一个独立的虚拟机
     这样设计就会在单个程序崩溃的情况下不会导致整个系统的崩溃)。
     adb shell getprop ro.build.version.release 查看系统版本号
     
     adb logcat >/Users/jiyajie/Desktop/log.txt adb导出运行时log日志
     
     adb shell am start -n com.android.settings/com.android.settings.Settings adb打开应用设置
     
     adb kill-server 杀死adb进程
     
     adb shell getprop ro.product.cpu.abi 查看手机cpu架构信息
     
     adb shell cat /proc/cpuinfo 获取cpu架构信息
     
     adb shell top 查看当前硬件下 cpu的实时占用情况
     
     adb shell am start -n com.android.settings/com.android.settings.HWSettings
     
     adb shell wm size 获取屏幕宽高信息
     
     adb shell pm clear com.xx.xx:清除对应包的数据和缓存
    
     鸿蒙设备: 进入setting adb shell am start -n com.android.settings/.HWSettings
     更改日期: adb shell 进去:   date 0825113620(11:36 8月25号20年)(按这个格式设置为当前时间)
     
     拷贝密码,鼠标放到【连接】按钮上,粘贴密码后,屏幕会变黑,直接在黑屏幕上点击连接
    

    性能优化相关

    卡顿优化方面:
     1.webView优化: 创建一个全局的webView 将web单独一个进程,用aidl进行通信
    
    启动优化:
     1.adb命令获取启动时间 adb shell am start -W 包名.SplashActivity
     ThisTime: 代表最后一个Activity启动时间
     TotalTime: 代表所有Activity的启动时间
     WaitTime: 所有时间: ams启动activity总耗时
     
     2.方法耗时统计: 在Application的onCreat方法下加入Debug.startMethodTracing("TracePath")
     
     总结: 主要分为两个方面: 1.业务流程优化(视觉欺骗)
     2. 代码优化(减少加载时间) ui优化 内存优化 图片优化/缓存优化 代码量优化
    

    进程间通信相关内容

     进程间通信:
     Binder通信的弊端: 1.aidl语法难写,容易发生编译异常 
     2.只支持基本类型,不支持对象类型
     3.当应用需要多个进程互相通信时需要多个aidl
     4.调用复杂容易出现异常,进程的调用者无法统一管理
    

    android 基础知识点范围

    java 相关知识点:
    
     Java 基础语法,Java 基本数据类型,Java 变量类型,Java 运算符,for,while,
     do...while,Java 条件语句,Java switch case,Java基础
     Java 对象和类,Java 字符串,Java 修饰符,Java Character 类,Java String 类,
     Java 数组
     Java Number & Math 类,StringBuffer 类,StringBuilder 类,Java 日期时间,
     Java 方法,输入、输出流与文件,
     Java Scanner 类,Java 异常处理,面向对象,线程,Java 继承,Java 重写(Override)
     与重载(Overload),Java 多态,
     Java 抽象类,Java 封装,Java 接口,Java 枚举(enum),Java 包(package),
     流程控制,Java 文档注释,Java 内部类
    
    
    android 基础知识点:
    
    活动,模拟器,布局组件,通用UI组件,消息通知组件,对话框组件,文件存储,共享存储,
    SQLite,Tween动画,Drawable动画,
     Property动画,Fast-json,Java语言,SwitchView,SugarORM,Android Studio,
     抽屉,活动发布,活动方向变化,
     拖放,事件队列和回调,退出活动,姿势,用户输入,用户交互,键盘输入
     
     SQLite 简介,命令,语法
     函数,运算符,注释符,通配符,数据类型
     信息安全: 实体安全,系统安全,网络安全
    
     Android 像素密度相关知识点dpi(dot per inch,每英寸点数):
         ldpi: 适用于低密度屏幕(120dpi) 的资源
         mdpi: 适用于中密度屏幕(160dpi) 的资源(这是基准密度)
         hdpi: 适用于高密度屏幕(240dpi) 的资源
         xhdpi: 适用于加高密度屏幕(320dpi) 的资源
         xxhdpi: 适用于超超搞密度屏幕(480dpi) 的资源
         xxxhdpi: 适用于超超超高密度屏幕(640dpi) 的资源
         nodpi: 适用于所有密度资源,这些是和密度无关的资源,不论当前dpi是多少,
         系统都不会缩放当前限定下的资源
    
         ldpi-->xxxhdpi 之间的缩放比: 3:4:6:8:12:16
    
         Android 中查找最佳匹配资源的规则:
         一般来说,Android会「更倾向于缩小较大的原始图像,而非放大较小的原始图像」。
         在此前提下:
    
        • 假设最接近设备屏幕密度的目录选项为xhdpi,如果图片资源存在,则匹配成功;
    
        • 如果不存在,系统就会从更高密度的资源目录下查找,依次为xxhdpi、xxxhdpi;
    
        • 如果还不存在,系统就会从「像素密度无关的资源目录nodpi」下查找;
    
        • 如果还不存在,系统就会向更低密度的资源目录下查找,依次为hdpi、mdpi、ldpi。
    
    
    kotlin 基础知识点:
    
     包声明、导入,注释,常量与变量定义,位操作符,字符,布尔,数组,IF表达式,When表达式,
     For循环,while与do...while循环,返回和跳转
     函数定义,常量与变量定义,字符串模板,NULL检查机制,类型检测及自动类型转换,区间,比较,类型转换,字符串
     字符串模板,类定义,类属性,主构造器,次构造函数,抽象类,内部类,匿名内部类,类修饰符,枚举常量
     协程,高阶函数等
     
      Kotlin中data class
      data class算是Kotlin中一大闪光点了
     
      data class就是一个类中只包含一些数据字段,类似于vo,pojo,java bean。
      一般而言,我们在Java中定义了这个数据类之后要重写一下toString,equals等方法。
      要生成get,set方法。
     
      然而在Kotlin中这些都不在需要自己手动去敲了,编译器在背后默默给我们生成了如下的东西:
     
      equals()/hashCode()
      toString()方法
     componentN()方法
     copy()方法
     如何申明一个简单的数据类? 有一下几点要求:
     
      主构造函数必须要至少有一个参数
      主构造函数中的所有参数必须被标记为val或者var
      数据类不能有以下修饰符:abstract,inner,open,sealed
     data class只能实现接口(Kotlin1.1以前的规则),现在也可以继承其它类
     
    data class User(var id: Int, var name: String)
     
     使用方式
     fun main(args: Array<String>) {
         var user: User = User(123,"liuliqianxiao")
         var user2: User = User(123,"liuliqianxiao")
         println(user.hashCode())
         println(user2.hashCode())
         println(user.equals(user2))// true
     
         println(user.toString())// User(id=123, name=liuliqianxiao)
     }
    
     kotlin for循环的集中方式:
    
     1,在Kotlin中想遍历1-100的数值可以这样写:
     for (index in 1..100){
                print(index)
            }
    
      2,这样写是正序遍历,如果想倒序遍历就该使用标准库中定义的downTo()函数:
      for (index in 100 downTo 1){
                print(index)
            }
      
      3,想不使用1作为遍历的步长,可以使用step()函数:
       for (index in 1..100 step 2){
                print(index)//会输出1..3..5......
            }
      
      4,要创建一个不包含末尾元素的区间:
      for (index in 1 until 10){
                println(index)//输出0..9
            }
      
      5,遍历一个数组/列表,想同时取出下标和元素:
       val array = arrayOf("a", "b", "c")
            for ((index,e) in array.withIndex()){
                println("下标=$index----元素=$e")
            }
    
      6,遍历一个数组/列表,只取出下标:
      val array = arrayOf("a", "b", "c")
            for (index in array.indices){
                println("index=$index")//输出0,1,2
            }
    
      7, 遍历取元素
      val array = arrayOf("a", "b", "c")
            for (element in array){
                println("element=$element")//输出a,b,c
            }
    
    

    android 组件化开发:

    ### android 组件化开发:
    组件化主要从三个方面进行拆分
    
     1. Gradle
    
     Gradle 内主要设置开关
     在Module(app)中,开关的目的是判断Module是否以library的方式在程序中运行
      在Module(module)中,来判断Module是library还是Application,从这两种方式中为Module设置不同的清单文件(两种方式的清单文件不同)
     
     2. 代码
    
     代码中组件化又笼统的分为三部分
     
        2.1 第一部分为library部分,组件化的App部分与Module不能直接交流,这时就需要一个library作为中间商,library可以被App和Module共同引入,
        所以通过library作为中间商最合适不过。 也可以将library理解为 MVP 模式中的 P层。
     
       2.2 第二部分则为Module部分,该部分根据开关,既可以作为library依赖于App部分运行,也可以作为一个单独的App运行(
       换句话说:当Module为library时,必须依赖于App部分才能运行,此时可以与App进行数据交互等操作。当Module作为Application时,
       Module就相当于一个独立的个体,与App部分不能进行数据交互,但是可以与其他依赖进行交互)
    
       2.3 第三部分为App部分,也是主程序部分,该部分位于程序的主界面,Module部分则作为主界面的组成成分。
     
     3 . 清单文件
    
     此部分主要分为两个模块
    
       3.1 当该模块作为Application时,为该模块设置一个自定义的Application,主要用于初始化操作
    
       3.2 为Module作为library和Application分别设置不同的清单文件
    
     必须要关注的几个部分
     1,application
       在common组件中有BaseAppliaction,提供全局唯一的context,上层业务组件在组件化模式下,均需继承于BaseAppliaction。
     
     2,applicationId管理
       可为不同组件设置不同的applicationId,也可缺省,在Android Studio中,默认的applicationId与包名一致。
       组件的applicationId在其build.gradle文件的defaultConfig中进行配置:
     
        if (Boolean.valueOf(rootProject.ext.isModule_North)) {
          //组件模式下设置applicationId
          applicationId "com.hailong.amd.north"
      }
     
      3,manifest管理
      组件在集成模式和组件化模式下,需要配置不同的manifest文件,因为在组件化模式下,程序入口Activity和自定义的Application是不可或缺的。
      在组件的build.gradle文件的android中进行manifest的管理:
    
    
         java插件引入了一个概念叫做SourceSets,通过修改SourceSets中的属性,
         可以指定哪些源文件(或文件夹下的源文件)要被编译,
         哪些源文件要被排除。
     
        sourceSets {
              main {
                  if (Boolean.valueOf(rootProject.ext.isModule_North)) {//apk
                      manifest.srcFile 'src/main/manifest/AndroidManifest.xml'
                  } else {
                      manifest.srcFile 'src/main/AndroidManifest.xml'
                      java {
                         //library模式下,排除java/debug文件夹下的所有文件
                         exclude '*module'
                     }
                 }
             }
         }
    
     4,资源名冲突问题
    
    
      * 限定所有子类xml中的资源文件的前缀
      * 注意:图片资源,限定失效,需要手动添加前缀
    
       资源名冲突问题,相信大家多多少少都遇到过,以前最常见的就是第三方SDK导致的资源名冲突了。
       这个问题没有特别好的解决办法,只能通过设置资源名前缀 resourcePrefix 以及约束自己开发习惯进行解决。
       资源名前缀 resourcePrefix ,是在project的build.gradle中进行设置的:
    
       //限定所有子类xml中的资源文件的前缀
       //注意:图片资源,限定失效,需要手动添加前缀
       subprojects {
         afterEvaluate {
             android {
                 resourcePrefix "${project.name}_"
             }
         }
      }
    
     这样设置完之后,string、style、color、dimens等中资源名,必须以设置的字符串为前缀,
     而layout、drawable文件夹下的shape他们的xml文件的命名,必须以设置的字符串为前缀,否则会报错提示。
    
     另外,资源前缀的设置对图片的命名无法限定,建议大家约束自己的开发习惯,自觉加上前缀。
    
     建议:
     将color、shape、style这些放在基础库组件中去,这些资源不会太多,且复用性极高,所有业务组件又都会依赖基础库组件。
    
     5,组件间跳转
     业务组件间不存在依赖关系,不可以通过Intent进行显式跳转,是要借助于路由的,例如开源框架ARouter
    
     我在案例中只使用了ARouter的基础的页面跳转功能,更复杂的诸如携带参数跳转、声明拦截器等
     功能的使用方法,大家可到Github上查看其使用文档。
    
     在每一个需要用到ARouter的组件的build.gradle文件中对其进行配置:
    
     android {
        ...
            defaultConfig {
              ...
             //Arouter路由配置
              javaCompileOptions {
                 annotationProcessorOptions {
                     arguments = [AROUTER_MODULE_NAME: project.getName()]
                    includeCompileClasspath = true
                 }
              }
          }
      }
        dependencies{
           ...
            //Arouter路由
            annotationProcessor rootProject.ext.dependencies["arouter_compiler"]
       }
     
        跳转目标页面配置:
       @Route(path = "/main/MainActivity")
       public class MainActivity extends BaseActivity {
        ……
       }
       跳转发起页面的发起调用:
    
        ARouter.getInstance()
               .build("/main/MainActivity")
               .navigation();
    
      6.第三方sdk集成问题
      项目不可避免的要使用第三方sdk,如友盟分享、高德地图、腾讯 bugly 等,
      都需要在相应第三方的开发者中心使用包名、applicationId注册,
      获取相应的 appkey 、appsecret等。那么,在组件化开发中,
      到底应该使用哪个组件的包名、applicationId 到第三方平台进行注册呢?
    
     我的想法是使用基础库的包名、applicationId 进行注册,
     然后将相应的第三方sdk的功能封装为功能组件,供上层业务组件进行调用。
    
     但也存在一个问题,即在第三方的管理平台上,将无法区分相应统计信息到底属于
     哪一个组件化app。
    
     所以还是要根据业务要求、统计要求自己选择了。
    

    IP协议浅析

    IP 协议浅析:
    物理层: 集线器(网线集合)

    数据链路层: 交换机(发送数据包的数据链路层需要知道 MAC 地址)

    网络层:路由器


    网络层不具有数据传输功能,数据传输在交换机

    如果两个ip在同一个子网下(通过子网掩码(255.255.255.0)判断ip地址是否在同一个子网下)则不通过路由器(网络层传输),

    如果不在同一个子网下则通过交换机把ip地址相关信息交给路由器,然后再找到对应的ip地址的交换机
    在交换机层(网络层),我需要把 IP 地址对应的 MAC 地址找到,
    也就是通过某种方式,找到 192.168.0.2 对应的 MAC 地址 BBBB。
    这种方式就是 arp 协议,然后再完成完整的数据传输

    相关文章

      网友评论

          本文标题:Android 工作手记

          本文链接:https://www.haomeiwen.com/subject/ndhfgrtx.html