一些总结

ADB全称Android Debug Bridge, 是android sdk里的一个工具。

它的主要功能有:

  • 运行设备的shell(命令行)

  • 管理模拟器或设备的端口映射

  • 计算机和设备之间上传/下载文件

  • 将本地apk软件安装至模拟器或android设备

查看设备

1
adb devices

安装软件

1
adb install [-r] [-s]

卸载软件

1
adb uninstall [-k] <软件名>

从电脑上发送文件到设备

1
adb push <本地路径> <远程路径>

用push命令可以把本机电脑上的文件或者文件夹复制到设备(手机)
例:传送文件到手机中,如:

1
adb push recovery.img /sdcard/recovery.img
adb

Http请求方式

Get

GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:http://api.juheapi.com/japi/toh?key=eff36bdaeeb868a6b8057a34f32d1326&v=1.0&month=11&day=1。

GET请求发送的参数如果数据是英文字母或数字,则按原样发送,如果是空格,则转换为+,如果是中文或其他字符,则直接把字符串用BASE64加密,得出如 %E4%BD%A0%E5%A5%BD 这类似的字符串,其中%XX中的XX为该符号以16进制表示的ASCII。

Post

POST请求的参数不是放在URL字符串里面,而是放在HTTP请求的正文内,请求的参数被封装起来以流的形式发送给服务端。

Get or Post?

对于GET方式提交数据的大小,HTTP协议并没有硬性限制,但某些浏览器及服务器会对它进行限制,如IE对URL长度的限制是2083字节(2K+35)。理论上POST也没有限制,可传较大量的数据。

POST的安全性要比GET的安全性高。比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为登录页面有可能被浏览器缓存,如果其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,除此之外,使用GET提交数据还可能会造成Cross-site request forgery(CSRF,跨站请求伪造)攻击。

一般来说,Get是向服务器索取数据的一种请求,而Post是向服务器提交数据的一种请求。

生成so文件

配置NDK环境变量

找到Android Studio安装的NDK包的文件目录(E:AndroidStudioSDKSDKndk-bundle),添加到系统的环境变量中

新建mk文件

在jni目录下新建Android.mk

1
2
3
4
5
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JNISample
LOCAL_SRC_FILES := com_lilei_testjni_JniUtils.cpp
include $(BUILD_SHARED_LIBRARY)

在jni目录下新建Application.mk文件

1
2
3
4
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions -std=c++0x
APP_ABI := armeabi-v7a
APP_PLATFORM := android-18

编译生成so

打开终端cd到jni目录下
调用ndk-build开始编译so

1
ndk-build

运行成功之后即会看到main文件夹下多了libs和obj的文件夹,里面就是生成的各种CPU的so文件

jni

环境配置

主要需要配置的就是NDK(Native Development Kit),现在Android studio很便利,可以一键下载: file → setting → 按截图找到如下路径 → 选择NDK → 确定应用下载

设置项目支持JNI

打开gradle.properties,添加:

1
android.useDeprecatedNdk=true

打开local.properties,添加:

1
ndk.dir=NDK的路径

最后打开app内build.gradle,在android/defaultConfig下面添加ndk配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.lilei.testjni"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
moduleName "JNISample"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

新建java访问c层的接口类

创建一个Jni的工具类,并定义接口函数,函数关键字用native(static用不用均可)

1
2
3
4
5
6
7
package com.lilei.testjni;
/**
* Created by lilei on 2017/3/29.
*/
public class JniUtils {
public static native String getJniString();
}

生成头文件

打开终端,运行

1
2
cd app/build/intermediates/classes/debug/
javah com.lilei.testjni.JniUtils

运行成功之后打开app/build/intermediates/classes/debug/ 即可找到编译出的头文件”com_lilei_testjni_JniUtils.h”,不难发现头文件名是有原报名+类名组成

创建jni开发的文件夹

点击app文件夹,New → Folder → JNI Folder, 选择在main文件夹下即可,生成成功后main目录下会出现一个jni的文件夹
找到刚才生成到头文件,复制到jni文件夹下(记得关闭刚才使用的终端,否则无法复制)
头文件有了,现在在jni目录下创建一个C++文件用于开发使用,命名与头文件相同
编写C++文件中定义函数的代码

1
2
3
4
5
6
#include "com_lilei_testjni_JniUtils.h"
JNIEXPORT jstring JNICALL Java_com_lilei_testjni_JniUtils_getJniString
(JNIEnv *env, jclass) {
// new 一个字符串,返回Hello World
return env -> NewStringUTF("Hello World");
}

java层加载so

回到JniUtils,加上

1
2
3
static {
System.loadLibrary("JNISample");
}

运行Run

调用jni的函数

1
2
3
4
5
6
7
8
9
10
11
12
package com.lilei.testjni;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("Jni", JniUtils.getJniString());
}
}

至此就成功运行出jni的Hello World了

一些总结

Git 取消上传文件

  1. 放弃对文件的修改 git checkout

  2. 假定没有修改文件 git update-index –assume-unchanged sdk_version.properties

SQLite notice

index 从 1 开始

fresco多图加载,缩略图预览

1
2
3
4
5
6
7
8
9
10
ImageRequest request = ImageRequestBuilder
.newBuilderWithSource(Uri.fromFile(new File(fileName)))
.setLocalThumbnailPreviewsEnabled(true)
.setResizeOptions(new ResizeOptions(DensityUtil.dip2px(context,120), DensityUtil.dip2px(context,120)))
.build();
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);

重点在于缩放

1
setResizeOptions(new ResizeOptions(DensityUtil.dip2px(context,120), DensityUtil.dip2px(context,120)))

身患懒癌的冬

手机拨号坏了,不能打电话,不能用电话薄,

所以自己做了个电话薄。新坑,还有两个地方没加上。

传送门

mvp做的。主要是为了练习编程模式。

mvp

通过URI获取的文件路径为null的解决方法

转载自大神dj0379博客Jingle的专栏

今天调用系统自带的FileChooser后,根据Intent返回的uri获取路径的时一直返回null。

这个问题很奇怪,最后发现验证用的华为P7是Android 4.4系统。

先看下4.4之前的uri的形式:

1
Uri : content://media/extenral/images/media/17766

是不是很熟悉?再看4.4及以后的Uri形式:

1
content://com.android.providers.media.documents/document/image%2706

日志一打印出来我就明白是什么原因啦。这什么东西在Android 4.4前后不一样,4.4之前content后面是文件全路径,4.4之后不再直接表示路径啦。这就好办啦,翻了翻API后发现4.4以后的Uri还不唯一,并不是统一的一种格式,所以就来个通用解决办法好啦:

4.4以前通过Uri获取路径:data是Uri,filename是一个String的字符串,用来保存路径。

URL