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
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 协议,然后再完成完整的数据传输
网友评论