Android防破解技术研究

人生如果错了方向,停止就是进步。

客户端和服务器通讯,key的存储方式一般有两种

一:动态从服务器获有时效性的key,失效的时候再去请求,这种额外增加了请求次数还要处理key失效的情况,如果用抓包软件还是可以破解key,相对来说不是太理想。

二:将私有的key通过native方法获取,打包后在so文件里面。但别人可以反编译代码,将你的so文件加载到自己代码里面,然后通过你的native方法去获取key,所以这边要解决下自己的so防止别人使用。
解决这个就是在native那边验证签名,不是自己签名不返回key,还可以让程序崩溃。这样基本上可以确保key的安全。

c代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static bool checkSignature = false;
// 检查签名是否被更改过
JNIEXPORT jboolean JNICALL Java_com_innotechx_jni_NativeUtils_checkSignature
(JNIEnv *env, jclass clazz, jobject context_object) {

jstring signature = Java_com_innotechx_jni_NativeUtils_getSignature(env, clazz, context_object);
const char *orginalSignature = "244699197";
const char *currentSignature = jstringTostring(env, signature);
int result = strcmp(orginalSignature, currentSignature);
return result == 0 ? true : false;
}
// 获取私有的key(用与加解密或者和服务器约定好的key)
JNIEXPORT jstring JNICALL Java_com_innotechx_jni_NativeUtils_getPrivateKey
(JNIEnv *env, jclass clazz, jobject context_object) {

if (false == checkSignature) {
checkSignature = Java_com_innotechx_jni_NativeUtils_checkSignature(env, clazz, context_object);
}
if (checkSignature) {
return env->NewStringUTF("这边返回你自己的key");
}
return env->NewStringUTF("获取失败");
}

Android通信篇EventBus

人生如果错了方向,停止就是进步。

EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。

作为一个消息总线,有三个主要的元素:

  • Event:事件
  • Subscriber:事件订阅者,接收特定的事件
  • Publisher:事件发布者,用于通知Subscriber有事件发生

EventBus in 3 step

1.定义Event:

1
public class MessageEvent { /* Additional fields if needed */ }

Javapoet生成java文件

如果你简单,这个世界就对你简单。

官方说明JavaPoet is a Java API for generating .java source files.

原由是看到了butterknife框架,里面用的是RetentionPolicy.CLASS,编译的时候通过注解实现框架的功能,比RetentionPolicy.RUNNTIME再通过反射实现效率高。
然后就去看RetentionPolicy.CLASS的实现原理,需要注解处理器(Annotation Processor),最后就一步步的看到了javapoet,自动生成java代码。
扯远了,直接记录过程吧。

一.过程搭建:

我是通过eclipse maven自动下载jar的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) throws IOException {
MethodSpec main = MethodSpec
.methodBuilder("main")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(void.class)
.addParameter(String[].class, "args")
.addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!").build();

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL).addMethod(main)
.build();

JavaFile javaFile = JavaFile.builder("com.zlc.javapoet",
helloWorld).build();
// 写入src目录下面
String path = System.getProperty("user.dir") + "/src";
javaFile.writeTo(new File(path));
}

RxJava学习

人生如果错了方向,停止就是进步。

RxJava Github基本用法都可以查考文档。

一.基本用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Observable<String> myObservaable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> t) {
t.onNext("Hello");
t.onCompleted();
}
});
Subscriber<String> mySubscriber = new Subscriber<String>() {
@Override
public void onNext(String t) {
System.out.println("onNext " + t);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onCompleted() {
}
};
myObservaable.subscribe(mySubscriber);

ios录制小视频(仿微信/钉钉)

人生一条路,走自己的路,
人生两个好,身体好,心情好
好好珍惜每一天!

公司的App里面需要添加个发送小视频功能,需要尽快搞出来,直接让模仿微信的小视频。查资料得出:

一.调用UIImagePickerController,这个相对来说比较简单,不过这个控制录制最大时长比较麻烦,代码如下:

1
2
3
4
5
6
7
8
9
10
- (IBAction)recordBegin:(id)sender {
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
ipc.cameraDevice = UIImagePickerControllerCameraDeviceRear;//设置使用哪个摄像头,这里设置为后置摄像头
ipc.mediaTypes = @[(NSString *)kUTTypeMovie];
ipc.videoQuality = UIImagePickerControllerQualityTypeIFrame1280x720;
ipc.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
ipc.delegate = self;
[self presentViewController:ipc animated:YES completion:nil];
}

SlideMenu和UIScrollView手势冲突

不闻不问不一定是忘记了,但一定是疏远了,彼此沉默太久就连主动的都需要勇气。

定义一个子类继承UIScrollView,重写- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer方法,做些判断就可以达达这效果。
目前我只做了向右滑动,菜单在左侧的冲突,右边依此类推很容易解决。以下Menu在左侧的解决方法:

aspectJ面向切面编程

一件事情,对你伤害的程度与事情本身没有任何关系,取决于你对这件事情的态度。

aop的实现我目前了解的有两种,一种是通过动态代理(实现InvocationHandler接口或者用第三方cglib库,两者区别这就不介绍了),另一种是aspectJ。aspectJ基本环境搭建,首先eclipse安装插件,aspect基本用法可以参考官方官方文档

一.Aspect基本用法,代码如下:

1.创建基本的main入口

1
2
3
4
5
6
7
8
9
10
package com.zlc.aj;
public class Test {
public void sayHello() {
System.out.println("Hello");
}
public static void main(String[] args) {
Test t = new Test();
t.sayHello();
}
}

笔记

BuildConfig.DEBUG 和 android:debuggable=”true” tools:ignore=”HardcodedDebugMode”

java

* IBM 技术分享http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/

android

* http://hannesdorfmann.com/annotation-processing/annotationprocessing101
* http://alighters.com/blog/2016/05/02/rxjava-plus-retrofitshi-xian-wang-luo-dai-li/  token失效处理

Android-SlidingPanLayout用法

人生一条路,走自己的路,
人生两个好,身体好,心情好
好好珍惜每一天!

先看效果
"图片描述"

1.左侧菜单栏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/slidingPaneLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
tools:context="com.innotect.slidingpanelayoutdemo.GeneralActivity">

<LinearLayout
android:layout_width="180dp"
android:layout_height="match_parent"
android:orientation="vertical">

<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/AppTheme.AppBarOverlay"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIcon="@mipmap/ic_launcher"
app:title="Slidingpanelayout基本用法"
app:titleTextColor="#FFFFFF" />

<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.v4.widget.SlidingPaneLayout>

Android—CoordinatorLayout用法

人生一条路,走自己的路,
人生两个好,身体好,心情好
好好珍惜每一天!

1.

先看效果
"图片描述"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="utf-8"?>"
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.innotect.coordinatorlayoutdemo.ScrollingActivity">

<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
app:layout_scrollFlags="scroll|enterAlways"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="与Scrollview" />
</android.support.design.widget.AppBarLayout>


<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:text="@string/large_text" />

</android.support.v4.widget.NestedScrollView>


</android.support.design.widget.CoordinatorLayout>