2019.1.16
1.在master分支打tag命令:git tag -a tag名 -m ‘注释’
例如:git tag -a v0.8.8 -m ‘巡更离线数据上线’
以上只是将标签添加到了本地的版本管理,我们需要在创建标签之后同步到远程仓库,使用以下命令:
推送所有本地标签:git push origin --tag
推送指定本地标签:git push origin 版本号。
查看远程所有分支(最好先执行git fetch --tags):git tag,
2.git 删除本地分支:git branch -d 分支名
3.git 删除远程分支:git push origin - -delete 远程分支名
例如:git push origin --delete xungeng
4.在mac下获取文件的路径,选中文件,然后command+option+c。
2019.2.28
1.删除分支:
1)删除本地分支命令:git branch -D 本地分支名
2)删除远程分支名:git push origin :远程分支名 (注意orgin后有个空格)
2019.3.4
1)switch可以放入的类型:char、int 、byte、short、Character、Integer、Byte、Short、enum。不能放入long类型。而且case后应该跟常量或常量表达式,不能像这样:case : inputTv.getText().toString():,这种情况编译是不通过的。
2) mac电脑强制退出某应用的命令:command+option+esc。这样会弹出正在运行的进程,选择你要杀掉的进程即可。
2019.3.6
1)ViewPager设置一屏幕显示左中右三个page的方法是,给ViewPager的父布局设置clipChildren = "false",该属性表示超出当前view的子view是否被切掉。该属性默认为true,表示超出该view的子view被切掉。
2019.3.12
1) git reset --hard 版本号
该命令是将代码回滚到指定的提交版本,代码回到指定版本号提交的代码状态。
2) git revert 版本号
该命令是将代码回滚到指定的提交版本修改之前的代码状态,也就是撤销了本版本号修改,回到了本版本号修改之前的状态,并且本版本号之后的提交记录也可以通过pull操作更新。该操作适合用来撤销代码提交误操作。
2019.3.13
1)导出手机里的anr文件夹:USB连接手机,在终端里输入命令:adb pull data/anr 。这样就会在当前的目录下下导出整个anr文件夹。
2) 尽量不要在onDraw()方法里创建临时对象,因为该方法在绘制的时候会被频繁调用,创建临时对象会导致一下创建大量临时对象,导致频繁GC操作,影响性能,也不要在onDraw()方法里做耗时操作,或复杂的计算。
2019.3.14
1)Android系统五层架构:
- 应用层:系统内置应用和开发者开发的应用都在该层。
- 应用架构层:包含一些Activity Manager、Location Manager、Package Manager等,给上层调用提供API。
- 系统运行库:提供一些C/C++库和Android运行时库。
- 硬件抽象层:Audio、Camera、BlueTooth等,也是各大Android手机厂商改动比较大的一层。
- Linux内核:系统的安全管理、进程管理等都依赖与该内核。
2)mac电脑杀进程快捷键:command+option+esc。
2019.3.21
1)Android系统的启动过程
- 启动电源,加载BootLoader引导程序到RAM中,然后执行。
- 引导程序把系统OS拉起来并运行。
- 引导程序启动Linux内核,当启动Linux内核时,设置缓存、被保护存储器、计划列表、加载驱动。
- 内核加载完成后,马上在系统文件里寻找init.rc文件,并马上要启动init进程。
- 启动init进程
2)init进程启动过程
- 创建和挂载启动所需要的文件目录。
- 初始化和启动属性服务。
- 解析init.rc配置文件并启动Zygote进程。
3)Zygote进程启动过程
- 创建AppRuntime并调用其main方法,启动Zygote进程。
- 创建Java虚拟机,并为Java虚拟机注册JNI方法。
- 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
- 通过registerZygoteSocket方法创建服务器端的Socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序进程。
- 启动SystemServer进程。
4)SystemServer进程被创建后主要做的工作:
- 启动Binder线程池,这样就可以与其他进程进行通信。
- 创建SystemServiceManager,用于对系统的服务进行创建、启动和生命周期管理。
- 启动各种系统服务(引导服务、核心服务、其他服务)。
2019.3.26
1.用adb命令安装apk到手机上:adb install /Users/zhuzhaoyang/sc/hkApp/android/qding-guanjia/build/outputs/apk/qa/release/qding-guanjia-qa-release.apk
2019.3.27
1.在Android8.0之前,未知应用安装权限默认开启,在8.0之后该权限默认关闭,需要在清单文件里配置<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>。不让在8.0以上手机,覆盖安装的时候会失败(下载完,安装的时候闪退)。
2019.4.2
1.关闭了系统通知权限后,Android原生吐司不显示,原因在Toast的show()方法里调用的有通知的INotificationManager,当关闭了通知权限后吐司就无法正常显示了。Toast的创建过程和通知栏没有关系,只是显示的时候有关系,创建过程参考原生Toast,通过调用WindowManager的addView()方法。
2019.4.4
1.在应用程序进程创建过程中,会启动Binder线程池,这样新创建的应用程序进程就支持Binder进程间通信了,我们只需要创建当前进程的Binder对象,并把它注册到ServiceManager中,就可以实现Binder进程间通信了,而不必关心进程间是如何通过Binder进行通信的。
2.在应用程序启动后,还会创建消息循环。这样运行在应用程序进程中的应用程序就可以方便的使用消息处理机制了。
2019.4.8
1.git 命令删除远端文件夹(将文件移出git仓库管理)
- cd 命令进入要删除的文件夹的父目录,执行以下命令先删除本地文件夹:git rm -r --cached 文件夹名字 。 # --cached表示不删除本地文件
- 再执行提交命令git commit -m 'ddd'
- 再将提交推送到远端git push
2019.4.11
IPC方式:
- 使用Bundle,通过Intent在三大组件(Activity、Service、BroadcastReceiver)中直接传递数据。这种方式最简单,但只能传递Bundle支持的类型(基本数据类型和实现了Parcelable或Serializable的对象)。
- 使用文件共享 。两个进程通过读写一个文件来交换数据。它只适合对数据同步要求不高的进程间通信,而且要妥善处理并发读写的问题。
- 使用Messenger。它是一种轻量级IPC方案,底层实现也是通过AIDL。可以将信息放入Message对象里作为载体,通过Messenger的send方法发送,能够传递的数据类型也局限与Bundle所支持的类型。Messenger的构造方法有两个,一个是通过传入一个IBinder类型对象,一个是通过传入一个Handler,在发送方在启动服务连接的回调里返回了一个IBinder对象(这个对象其实是Service的onBind()方法返回的,返回的是Messenger对象的getBinder()),通过这个IBinder对象,我们可以向服务端发送消息,在服务端我们可以通过传入一个Handler来创建Messenger,该handler用来处理接收到的消息。如果需要服务端向客户端发消息,那么需要在客户端向服务端发消息的Message对象里传入一个客户端用来处理消息的Messenger对象,通过msg.replyTo = Messenger对象,该Messenger对象通过传入一个Handler对象创建,handler对象用来接收处理服务端回发的消息。缺点:Messenger是通过串行的方式处理客户端发来的消息的,如果有大量消息同时发送到服务端,服务端只能一个一个处理,所以并发请求,Messenger并不合适。而且Messenger的主要作用是传递消息,很多时候我们还需要调用服务端的方法,这种情况Messenger就做不到,可以通过AIDL来实现跨进程方法调用。
2019.4.19
1.在增强for循环(foreach)里不能直接用集合提供的的add/remove方法,原因是增强for其原理是借助Iterator进行遍历的,当iterator进行下一次遍历的时候,经检测发现有一次集合的修改操作并不是通过自身完成的,那么可能是发生了并发被其他线程执行,这时候就会抛异常,提示用户可能发生了并发修改。
解决办法:1)使用普通的for循环,在普通的for循环里add,remove。
2)使用集合的迭代器Iterator,当需要remove的时候调用迭代器自身的remove方法。
3)使用java8提供的filter过滤。
2019.4.23
1.如何实时获取当前屏幕中Activity的名称?
如果是单纯获取屏幕中activity的名称,可以有以下3种方法:
1)使用命令:adb shell dumpsys activity top
2)通过系统服务:ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> appList3 = manager.getRunningTask(1000);
3)通过Android Studio 提供的Profile工具,查看当前的topActivity。
实时获取屏幕中Activity的话,相当于是监听屏幕界面发生的变化。可以使用一种特殊的服务---AccessibilityService,它的设计初衷是为了帮助残障用户使用Android设备和应用。它运行在后台,可以监听用户的一些状态变化,比如,页面切换、状态改变、通知、Toast等,并在触发AccessibilityEvents时由系统调用。
使用过程:
1)编写自己的服务类,继承AccessibilityService,重写onServiceConnected()方法、onAccessibilityEvent()方法和onInterrupt()方法,有关AccessibilityEvent事件的回调函数,系统通过sendAccessibiliyEvent()不断的发送AccessibilityEvent()回调方法。
2)在清单文件里声明定义的服务,并添加绑定该服务的权限
label是你的应用在系统设置的“无障碍”页面里的名字。
3)在meta-data里配置用来指定接收的事件。
4)启动服务。我们需要在系统设置的“无障碍”页面里,手动打开该项功能,否则无法继续进行。通过以下代码自动打开系统无障碍功能列表。
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(intent);
设置打开成功后,会回调服务的连接成功方法。
5)处理事件信息。由于我们监听了事件的通知栏和界面等信息,当我们指定packageNames的通知栏或者界面发生变化时,会通过onAccessibilityEvent回调我们的事件,接着进行事件的处理。
2019.4.24
1.多线程的实现方式有哪些?
继承Thread类,实现Runnable接口,最后调用start()方法启动线程。
2.start()方法和run()方法的区别与联系?
调用start()方法后,线程处于就绪状态,并没有真正的运行,在获取到CPU的时间片后,才执行run()方法,run()方法里面是我们的线程体。直接调用run()方法和普通的方法调用类似,在主线程中执行,并不会开启线程。
3. 什么是线程:线程是系统可调度和分派的基本单位,自己不拥有系统资源,只拥有一点运行中必不可少的资源。线程有创建、就绪、执行、阻塞、销毁五个基本状态。
4.什么是多线程:一个进程中同时多个线程同时执行。
5.为啥使用多线程:为了解决负载均衡问题,为了重复使用CPU资源,提高CUP使用率,采用多线程的方式同时实现几件事情而互不干扰。为了处理大量的IO操作,或其他需要花费大量时间的操作。
6.并发和并行的区别:
并发:一个CPU,通过CPU调度算法,处理多个任务的能力。
并行:多个CPU,同时处理多个相同的任务的能力。