0%

一、常见数据类型

JavaScript中可以用typeof获取某个变量的数据类型,常见的数据类型有:number,string,boolean,object,function,undefined,直接看代码:

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
let a = 1;
let b = 1.222;
alert(typeof(a)); // number
alert(typeof(b)); // number

let c = '1';
let d = 'hello';
let k = '';
alert(typeof(c)); // string
alert(typeof(d)); // string
alert(typeof(k)); // string

let e = true;
alert(typeof(e)); // boolean

let m = window;
let n = {};
let p = null;
let q = [1, 2, 3];
alert(typeof(m)); // object
alert(typeof(n)); // object
alert(typeof(p)); // object
alert(typeof(q)); // object

let fun = function() {}
alert(typeof(fun)); // function

let json = {}
alert(json.a); // undefined
let y;
alert(y); // undefined
let fun1 = function(){
return;
}
alert(fun1()); // undefined
let fun2 = function(){}
alert(fun2()); // undefined
Read more »

变量、常量、数组

定义变量使用var,定义常量使用val,Kotlin会根据值自动推断类型,不需要自行指定,如下:

var a = 1
val b = 2

当然你要指定也可以:

var a: Int = 1

定义可空变量和常量:

var android: String? = null
val name: String? = null
Read more »

一、前言

EventBus是一个开源的事件总线框架,Android中被广泛使用,目前最新的版本为3.2.0,github地址:https://github.com/greenrobot/EventBus

二、简单使用

  1. 在build.gradle中引入依赖:

    implementation 'org.greenrobot:eventbus:3.2.0'
  2. 定义事件实体类:

    public class CallEvent {
    }
  3. 订阅消息:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
    
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEvent(CallEvent event) {
        // TODO 
    }
  4. 发送消息:

    CallEvent event = new CallEvent();
    EventBus.getDefault().post(event);
  5. 来到这里就可以把EventBus用起来了,不过这里有个问题,注册时会反射遍历注册类的所有被Subscribe注解的方法,这个过程比较耗时会影响性能,因此EventBus又提供了一个eventbus-annotation-processor库来解决该问题,因此我们把它引入进来:

    annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.0.1'
  6. 这个eventbus-annotation-processor还需要一个key为eventBusIndex的键值对,用来指明自动生成的类的类名:

    android {
        defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [ eventBusIndex : 'org.greenrobot.eventbusperf.MyEventBusIndex' ]
                }
            }
        }
  7. 然后编译代码,就可以在build/source/apt/debug/下看到自动生成了org.greenrobot.eventbusperf.MyEventBusIndex类,这时我们需要把这个类添加到EventBus中:

    EventBus.builder()
        .addIndex(new MyEventBusIndex())
        .installDefaultEventBus();
  8. 配置到此结束,可以愉快地使用了。

Read more »

题意

As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Correct parentheses sequences can be defined recursively as follows:
1.The empty string “” is a correct sequence.
2.If “X” and “Y” are correct sequences, then “XY” (the concatenation of X and Y) is a correct sequence.
3.If “X” is a correct sequence, then “(X)” is a correct sequence.
Each correct parentheses sequence can be derived using the above rules.
Examples of correct parentheses sequences include “”, “()”, “()()()”, “(()())”, and “(((())))”.

Now Yuta has a parentheses sequence S, and he wants Rikka to choose two different position i,j and swap Si,Sj.

Rikka likes correct parentheses sequence. So she wants to know if she can change S to a correct parentheses sequence after this operation.

It is too difficult for Rikka. Can you help her?

Read more »

一、简单使用

  1. Application中初始化:

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        ......
        ARouter.openLog();
        ARouter.openDebug();
        ARouter.init(this);
        ......
    }
  2. 在目标Activity加上注解:

    @Route(path = "/activity/second")
    public class SecondActivity extends Activity {
    
        ......
    }
  3. 跳转到目标Activity:

    ARouter.getInstance().build("/activity/second").navigation();

    可以看到,对于实现Activity跳转,使用起来很简单,思路清晰,代码不多。

Read more »

先推荐一下官方的Android源码查看网站:Android Code Search,功能很强大,用起来很方便。

原理分析

之前写过一篇文章:深入理解Android中的SharedPreferences,现在抛开源码,总结成几个关键点:

  1. 只要file name相同,拿到的就是同一个SharedPreferencesImpl对象,内部有缓存机制,首次获取才会创建对象。

  2. 在SharedPreferencesImpl构造方法中,会开启子线程把对应的文件key-value全部加载进内存,加载结束后,mLoaded被设置为true。

  3. 调用getXXX方法时,会阻塞等待直到mLoaded为true,也就是getXXX方法是有可能阻塞UI线程的,另外,调用contains和
    edit等方法也是。

  4. 写数据时,会先拿到一个EditorImpl对象,然后putXXX,这时只是把数据写入到内存中,最后调用commit或者apply方法,才会真正写入文件。

  5. 不管是commit还是apply方法,第一步都是调用commitToMemory方法生成一个MemoryCommitResult对象,注意这里会先处理clear旧的key-value,再处理新添加的key-value,另外value为this或者null都表示需要被remove掉。

  6. 调用commit方法,就会同步执行写入文件的操作,该方法是耗时操作,不能在主线程中调用,该方法最后会返回成功或失败结果。

  7. 调用apply方法,就会把任务放到QueuedWork的队列中,然后在HandlerThread中执行,然后apply方法会立即返回。但如果是Android8.0之前,这里就是放到QueuedWork的一个单线程中执行了。

  8. 最后是写入文件,会先把原有的文件命名为bak备份文件,然后创建新的文件全量写入,写入成功后,把bak备份文件删除掉。

Read more »

Android P非SDK接口限制

1. 三种名单

  • 黑名单:不可使用,否则会抛出异常。

  • 灰名单:如果当前apk的API级别<接口的限制API级别,那么可以用,否则抛出异常。

  • 白名单:受支持的接口,可以使用。

2. 抛出异常

如果使用了黑名单的接口,就会抛出异常,调用getDeclaredField()方法会抛出NoSuchFieldException,调用getDeclaredMethod()方法会抛出NoSuchMethodException。

Read more »

前言

ThreadLocal是JDK中的一个类,很多基础框架和平时开发中都会使用到,因此有必要弄清其内部原理,才能更好地使用它。

使用方法

要弄清原理,还是要先知道如何使用,ThreadLocal用起来是很简单的,一般都是把ThreadLocal定义为static变量,也就是只有一个实例对象,如下:

private static ThreadLocal<Integer> sThreadLocal = new ThreadLocal<Integer>();
Read more »

前言

okhttp是目前很火的网络请求框架,Android4.4开始HttpURLConnection的底层就是采用okhttp实现的,其Github地址:https://github.com/square/okhttp

来自官方说明:

OkHttp is an HTTP client that’s efficient by default:

  • HTTP/2 support allows all requests to the same host to share a socket.
  • Connection pooling reduces request latency (if HTTP/2 isn’t available).
  • Transparent GZIP shrinks download sizes.
  • Response caching avoids the network completely for repeat requests.
Read more »

前言

新建一个AS工程,编译器会自动帮我们创建了Gradle Wrapper相关的文件,目录结构如下:

├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
Read more »