一、adb启动activity、service、发广播
1、adb启动activity:
$ adb shell
$ am start -n {包(package)名}/{包名}.{活动(activity)名称}
如:启动浏览器
# am start -n com.android.browser/com.android.browser.BrowserActivity
2、adb启动service:
$ adb shell
$ am startservice -n {包(package)名}/{包名}.{服务(service)名称}
如:启动自己应用中一个service
# am startservice -n com.android.traffic/com.android.traffic.maniservice
3、adb发送broadcast:
$ adb shell
$ am broadcast -a <广播动作>
如:发送一个网络变化的广播
# am broadcast -a android.net.conn.CONNECTIVITY_CHANGE
二、OpenGL ES
OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL,后来因为IRIS GL移植性不好,所以在其基础上开发了OPenGL,OpenGL一般用于图形工作站PC端使用,由于性能各方面原因,在移动端使用OpenGL基本带不动,为此Khronos公司就为OpenGL提供了一个子集Open ES(OpenGL for Embedded System),移动端使用的基本都是OpenGL ES,Android还专门为OpenGL提供了android.opengl包,并提供了GlSrufaceView、GLU、GlUtils等工具。
在Android框架里面两个基本的类允许你使用OpenGL ES API创建和操作图形: GLSurfaceView 和 GLSurfaceView.Renderer
GLSurfaceView :这是一个视图类,你可以使用OpenGL API来绘制和操作图形对象,这一点在功能上很类似于SurfaceView。你可以通过创建一个SurfaceView的实例并添加你的渲染器来使用这个类。但是如果想要捕捉触摸屏的事件,则应该扩展GLSurfaceView以实现触摸监听器。
GLSurfaceView.Renderer:此接口定义了在GLSurfaceView中绘制图形所需的方法。您必须将此接口的实现作为单独的类提供,并使用GLSurfaceView.setRenderer()将其附加到您的GLSurfaceView实例。
GLSurfaceView.Renderer要求实现以下方法:
- onSurfaceCreated():创建GLSurfaceView时,系统调用一次该方法。使用此方法执行只需要执行一次的操作,例如设置OpenGL环境参数或初始化OpenGL图形对象。
- onDrawFrame():系统在每次重画GLSurfaceView时调用这个方法。使用此方法作为绘制(和重新绘制)图形对象的主要执行方法。
- onSurfaceChanged():当GLSurfaceView的发生变化时,系统调用此方法,这些变化包括GLSurfaceView的大小或设备屏幕方向的变化。例如:设备从纵向变为横向时,系统调用此方法。我们应该使用此方法来响应GLSurfaceView容器的改变。
具体用法:
GLSurfaceView glSurfaceView = new GLSurfaceView(this);
glSurfaceView.setRenderer(new GLSurfaceView.Renderer() {
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
}
@Override
public void onSurfaceChanged(GL10 gl10, int i, int i1) {
}
@Override
public void onDrawFrame(GL10 gl10) {
}
});
setContentView(glSurfaceView);
三、Android5.0系统以上Button的字母默认是大写的,可以这样去掉:
android:textAllCaps="false"
或者
textView.setAllCaps(false);
四、Java 中URL和URI的区别
1、URI: 表示一个统一资源标识符 (URI) 引用。英文全称是UniformResource Identifiers
mailto:java-net@java.sun.com
news:comp.lang.java
urn:isbn:096139210x
http://java.sun.com/j2se/1.3/
docs/guide/collections/designfaq.html#28
../../../demo/jfc/SwingSet2/src/SwingSet2.java
一个URI有九个组成部分,看下表:
URI.create(String s);它可以根据给定的字符串,按照URI的规则进行解析,从而得到一个URI实例,URI还提供一个toURL()方法将URI转化成一个URL
2、URL:代表一个统一资源定位符,它是指向一个互联网“资源”的指针。互联网是关键,URL指向的资源都是网络资源,所以它需要指定一个具体的协议。
一些URL的例子:
http://java.sun.com/index.html#chapter1
http://www.socs.uts.edu.au:80/MosaicDocs-old/url-primer.html
URL提供了toURI()方法, 可以将一个URL转化成URI,URL可以通过OpenConnection()获得一个URLConnection对象,而URLConnection可以对网络资源进行操作:
public static void main(String[] args){
URI uri = URI.create("http://www.baidu.com") ;
URLConnection urlConnection = null;
try {
urlConnection = uri.toURL().openConnection();
} catch (IOException e) {
e.printStackTrace();
}
try {
InputStream inputStream =urlConnection.getInputStream() ;
InputStreamReader isr = new InputStreamReader(inputStream) ;
char[] c = new char[1024] ;
while (isr.read(c)!=-1){
System.out.print(c) ;
}
} catch (IOException e) {
e.printStackTrace();
}
}
五、一般新建的Activity布局中都会出现 tools:context=".MainActivity"
这个属性的意思是:如果你在AndroidManifest.xml文件中为某个activity设置了Theme样式,那么,一般情况下,你在layout布局里面是无法直接看到这个效果的。因为一份layout布局可以提供给很多个activity用,layout无法知道自己提供给了哪个activity,而这个activity又设置了怎样的样式。所以,我们要为layout设置这样一个属性,来告诉layout当前提供给了哪个activity使用,从而实时显示这个activity所设置的样式效果(如果有)。
也就是layout ----> activity ---->Theme,建立起了链接。否则,即使你为activity设置了样式,你的layout布局文件也是不知道的。
六、获取sha1
我们使用Android Studio 运行或测试我们的app 它使用一个默认的debug.keystore进行签名,它位于C:\Users\jack.dong\.android下,具体看你的sdk装在哪个用户下,我的是jack.dong,他的默认密码是“android”,一般我们生成sha1码的时候可以在工程下方的Terminal中输入:keytool -list -v -keystore debug.keystore,然后输入密码,点击回车即可, 这里输入密码:“android”
七、引用library的方式和区别
1、implementation和api是取代之前的compile的,其中api和compile是一样的效果,implementation有所不同,通过implementation依赖的库只能自己库本身访问,举个例子,A依赖B,B依赖C,如果B依赖C是使用的implementation依赖,那么在A中是访问不到C中的方法的,如果需要访问,请使用api依赖
2、compileOnly
和provided
效果是一样的,只在编译的时候有效, 不参与打包
3、releaseImplementation
和releaseCompile
效果相同,只在release
模式和打包release包情况下有效
4、runtimeOnly
和 apk
效果一样,只在打包的时候有效,编译不参与
八、依赖的常用参数
compile('org.hibernate:hibernate:3.1') {
// 冲突时优先使用该版本
force = true
// 依据名称排除
exclude module: 'cglib'
// 依据组织名称排除
exclude group: 'org.jmock'
// 依据组织名称+名称排除
exclude group: 'org.unwanted', module: 'iAmBuggy'
// 为本依赖关闭或者打开依赖传递特性,为false表示不下载该依赖包所依赖的其他库。另一种解释是是否传递本身的依赖给宿主程序(使用传递依赖时,Gradle 会将传递依赖一起下载下来。compile和api 默认是开启传递依赖,implementation默认不开启传递依赖)
transitive = true
}
动态版本依赖:
使用场景:保持工程依赖都是最新版本。
使用方式:+,可以让gradle每次构建时检查远程仓库是否存在最新版本,若存在则下载。也可指定某个大版本下的最新子版本,1.+,表示始终依赖最新的 1.x 版本。
compile 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.+'
九、RecyclerView嵌套
// 重写里层RecyclerView
recyclerView.setLayoutManager(new LinearLayoutManager(this){
@Override
public boolean canScrollVertically() {
//解决ScrollView里存在多个RecyclerView时滑动卡顿的问题
//如果你的RecyclerView是水平滑动的话可以重写canScrollHorizontally方法
return false;
}
});
//解决数据加载不完的问题
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(true);
//解决数据加载完成后, 没有停留在顶部的问题
recyclerView.setFocusable(false);
十、静态内部类
静态内部类并不是一开始就创建的!它与静态成员不一样,并不能直接通过外部类名.内部类名的方式就可以直接访问并得到它的对象,通俗一点来说就是:静态内部类跟正常的一个外部类一样,它需要创建才能有,静态内部类并不会依赖于任何一个外部类实例,它可以在适当的时候被系统回收,并不会造成内存泄漏!所以,静态内部类对象的生命跟普通的对象一样,生命开始于开发者创建它,结束于系统回收它!
一般我们在Activity或者Adapter把内部类都设置为静态内部类, 这样可以强制内部类不会持有外部类的对象,从而避免内存泄漏。
十一、为zxing扫码添加光线检测和预览放大效果
Android高仿微信/支付宝 扫一扫(弱光检测扫一扫自动放大功能)_android二维码放大_PRIMEZPY的博客-CSDN博客
十二、虚线drawable
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">
<stroke
android:width="1dp"
android:color="#eee"
android:dashGap="5dp"
android:dashWidth="5dp"/>
</shape>
注意,想要虚线效果出来,相应的View还有设置android:layerType="software",不然的话,只会显示实线
十三、拦截蓝牙2.0配对输入pin嘛的对话框
首先在Manifest里注册广播:
<receiver android:name=".receiver.BluetoothConnectReceiver" >
<intent-filter android:priority="1000">
<action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
</intent-filter>
</receiver>
public class BluetoothConnectReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
BluetoothDevice mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
try {
//(三星)4.3版本测试手机还是会弹出用户交互页面(闪一下),如果不注释掉下面这句页面不会取消但可以配对成功。(中兴,魅族4(Flyme 6))5.1版本手机两中情况下都正常
//ClsUtils.setPairingConfirmation(mBluetoothDevice.getClass(), mBluetoothDevice, true);
abortBroadcast();//如果没有将广播终止,则会出现一个一闪而过的配对框。
//3.调用setPin方法进行配对...
// boolean ret = bluetoothDevice.setPin("1234".getByte());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
十四、封装http请求回来数据解析
1、公共处理
请求回来的数据我们一般会做一层拦截, 做一些公共处理,一般用JsonObject obj = new JsonObject(requestStr); 来做,然后把code字段用obj.getInt("code")或者obj.getString("code")拿到, 例如用户登录了其他设备,此设备要退出, 或者在开发的过程中没有了权限, 这在任何一个接口都有可能出现。
2、解析
当拿到请求回来的数据后有两种操作,如果我们跟后端约定直接拿到code、data、msg格式的mock数据,可以由每个业务自己去用GsonFormat生成实体类,如果跟后端约定只给了data部分数据,那么我们可以这么做:
public class CommonClass<T> {
String code;
String msg;
T data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
//万一服务端不给msg字段呢? 难道业务里都去各种判断?
public String getMsg() {
return msg == null ? "" : msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
// 业务用这个来解析, 把自己的data实体用泛型传进来就可以了
CommonClass<TrystoreOrderBean> bean = JSON.parseObject("json", CommonClass.class);
CommonClass<ArrayList<TrystoreOrderBean>> bean = JSON.parseObject("json", CommonClass.class);
十五、横竖屏切换声明周期以及数据保存处理
当横竖屏切换的时候,界面会先销毁,然后重新创建, 在这个过程中会调用如下接口让你有机会在onSaveInstanceState()中保存数据,然后在onCreate或者在onRestoreInstanceState()恢复数据:
onSaveInstanceState() -> onCreate() -> onRestoreInstanceState()
在平板开发中一般横屏界面和竖屏界面布局不相同,横竖屏切换可以在onCreate中判断参数Bundle是否为空, 如果不为空就恢复数据, 如果为空就去请求数据。
当你不想让屏幕重启的时候可以设置:
android:configChanges="keyboardHidden|orientation|screenSize"
当你不想让他销毁,还想让屏幕在一个方向上旋转的时候:
android:screenOrientation="sensorLandscape"
注意:直接设置成landscape他就不旋转了
十六、生成jks文件
keytool -genkey -v -keystore ~/文件名.jks -keyalg RSA -keysize 2048 -validity 10000 -alias 别名 -storetype JKS
回车后输入密码和别名密码即可