Gradle quick start

What is Gradle

To me, i use it to replace ‘make’ and ‘autotools’.

Download/Install

Download and Install/Java Quick Start.
Then configure it in .bashrc:

export GRADLE_OPTS="-DsocksProxyHost=127.0.0.1 -DsocksProxyPort=9999"
#export GRADLE_OPTS=-Dorg.gradle.daemon=true
export GRADLE_HOME=/home/y/.programs/gradle-2.5
export PATH=$GRADLE_HOME/bin:$PATH

gradle directory structure

default

By default Gradle uses standard Maven project structure.
Reference:
https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
https://docs.gradle.org/current/userguide/java_plugin.html

src/main/java --> java source code
src/main/resources --> other files needed, like logback.xml and log4j.properties
src/test/java --> unit tests

After “gradle build”, a directory “build” will appear, jar file is in build/libs.

get resource file in code:

File f1 = new File(getClass().getClassLoader().getResource("binary_tree_1.ser").getFile());

改变默认src/res位置

如果是android project,sourceSets需要放到android object里面

sourceSets {
    main {
        java {
            srcDir 'src'
        }  
        res {
            srcDir 'res'
        }  
        resources {
            srcDir 'src'
        }
        assets {
            srcDir 'assets'
        }
        manifest {
            srcFile 'AndroidManifest.xml'
        }
    }//main
}//sourceSets

Gradle support in vim/IDE

gradle support in VIM:(it needs pathogen.vim) by vim-gradle

gradle is also supported in Intellij.

文档

google提供的配置android的gradle
https://developer.android.com/tools/building/configuring-gradle.html

常用配置

配置静态变量

buildTypes {
    debug {
        buildConfig "public final static boolean HAS_PROTOTYPE_FEATURE = true;"
    }
    release {
        buildConfig "public final static boolean HAS_PROTOTYPE_FEATURE = false;"
    }
}

配置依赖项目

dependencies {
    compile project(':library')
}

配置依赖jar目录

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
}

配置依赖jar文件

dependencies {
    compile files (
        'libs/gcm.jar',
        '...more-jar-files...'
    )
}

配置gradle run

可执行任务gradle run相当于java -jar xxx

task pack_clear(type: JavaExec, dependsOn:[':pack_ramdisk_and_gz', 'build']) {
    description '运行指定main函数的java'
    classpath = sourceSets.main.runtimeClasspath
    main = "cfig.bootimg.repack_with_cmd"
    args rootProject.outClearIMg, rootProject.rootWorkDir, rootProject.mkbootimgBin
}

对于gradle, 如果mai在src/main/groovy/cfig/exec.groovy, 则main = “cfig.exec”

指定gradle版本

buildscript {
    repositories {
          mavenCentral()
    }
    dependencies {
          classpath 'com.android.tools.build:gradle:1.3.1'
    }
}

两步编译jar

load进plugin

apply plugin: 'java'

指定main class

jar {
    manifest {
        attributes 'Main-Class': 'org.cfig.gradle.Hi'
    }
}

或者定制更多:

jar() {
    from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}
    archivesBaseName = "Hi"
    manifest {
        attributes 'Implementation-Title': 'Good Day',
                   'Implementation-Version': '1.0',
                   'Main-Class': 'cfig.Hi',
                   'BUILD_TIME': '2015.11.11'
    }
}

或者创建类型为Jar的task

task mkbootimg(type: Jar, dependsOn:['build']) {
    from files(sourceSets.main.output.classesDir)
    from configurations.runtime.asFileTree.files.collect { zipTree(it) }
    baseName = 'mkbootimg'
    manifest {
        attributes 'Main-Class': 'cfig.bootimg.mkbootimg'
    }
}

using gradlew

read this first.
add the following block to the bottom of your build.gradle

task wrapper(type: Wrapper) {
    gradleVersion = '4.0'
}

Run the following command to download and initialize the wrapper scripts:

gradle wrapper

enable stdout in test

test {
    testLogging {
        showStandardStreams = true
    }
}

forece a test task even everything is UP-TO-DATE

gradle test --rerun-tasks

init gradle project

gradle init --type basic
gradle init --type groovy-library
gradle init --type java-library

intellij idea tips

shortcuts

CTRL+ALT+L format code

ALT+7 structure view

File | Project Structure | Artifacts
then you should press alt+insert or click the plus icon and create new artifact choose –> jar –> From modules with dependencies.

Next goto Build | Build artifacts –> choose your artifact.

Quick Fix:
Alt+Enter

Create sth:
CTRL+ALT+INSERT

Quickly create jar from java project

  1. “Project Setting” -> “Artifacts” -> “+” -> “Jar” -> “from modules with dependencies”
  2. build artifact

Handling_Runtime_Changes

app need to Handling Runtime Changes such as [keyboard|keyboardhide|oritation].

1. if app doesn’t explicitely handle such changes, android does

android(ActivityStack.java##ensureActivityConfigurationLocked()) will restart the running Activity (onDestroy()->onCreate()), so app needs to implement onSaveInstanceState(),

2. else app need to explicitely handle changes

2.1 Retain an object during a configuration change

allow activity restart, but carry a stateful object to the new activity instance, read this

2.2 Handle the configuration change yourself

disable activity restart, handle the config change event in a callback.

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);

// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}

This is a list of all android:configChanges events and the Configuration class.

regex

There’s a great blog post about Lookahead/Lookbehind(先行断言,后行断言)

Oracle API about java/util/regex/Pattern.html

Read config file with regex:

target file: updatedb.conf

 PRUNE_BIND_MOUNTS ="yes"
# PRUNENAMES=".git .bzr .hg .svn"
PRUNEPATHS="/tmp /var/spool /media"
PRUNEFS =  "NFS"

grep test:

$ grep -Po "(?<=PRUNEPATHS=).*" updatedb.conf

结果

"/tmp /var/spool /media"

Find a tag name in xml:(with bug)

grep -P "(?<=<)[^<>/]+(?=>)" /etc/cupshelpers/preferreddrivers.xml

前面有<, 中间没有<>?, 后面有>, 匹配中间
bug:
不能区分,和注释

grep -P "(?<=<)[^< >/]+(?=( |>))" /etc/cupshelpers/preferreddrivers.xml

前面有<, 中间没有< >?, 后面有>或者SPACE, 匹配中间
bug:
不能过滤注释

?=可以用来分组,但不捕获

grep -P "^[-+]?\d*\.?\d*$" list
list
7.
5.56
0.123
1.23
5
77654
-3
-2.0
-0.33
+833
0.0.2
.23
advg
-adf
-3.f
-f.3
+3.f
+f.3
.
+kj33f

bug: 还能匹配到.

git filter-branch –commit-filter ‘export GIT_AUTHOR_NAME=”cfig”; git commit-tree “$@”‘
git update-ref -d refs/original/refs/heads/master

Hello Hexo

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in trobuleshooting or you can ask me on GitHub.

Quick Start

Misc

steps to create new blog site:

$ hexo init (hexo will complain if anything wrong, make it happy)
$ npm install (hexo will ask U to do so)
$ hexo server

Add google analytics into hexo:

  1. Get “tracking ID” from Google
  2. add “tracking ID” in themes/landscape/_config.yml

Create a new post

$ hexo new "My New Post"

More info: Writing

Run server

$ hexo server

More info: Server

Generate static files

$ hexo generate

More info: Generating

Deploy to remote sites

$ hexo deploy

More info: Deployment

Hexo configuration

全部禁用分页

per_page: 0

archive禁用分页,主页使用分页

per_page: 3

archive_generator:
  per_page: 0
 yearly: true
  monthly: true

category_generator:
  per_page: 0

tag_generator:
   per_page: 0

启动hexo-local-image插件

npm install hexo-local-image --save

插件下载后有README.md,配置_config.yml

plugins:
    - hexo-local-image

新版hexo默认不提供server插件,需要手动加:

npm install hexo-server --save

添加plantuml插件

npm install hexo-tag-plantuml –save

action_bar

action bar

1. intro

the action bar displays the title for the activity and the app icon on the left
android:minSdkVersion=”11”(ICS), use android:theme="@android:style/Theme.Holo" as theme parent will have ActionBar support.

2. add basic actionbar

create options menu

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_layout);
getActionBar().setDisplayHomeAsUpEnabled(true);//up button go to parent activity
}

handle options menu actions

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.action_call:
        return true;
    case R.id.action_search:
        Intent aI = new Intent(this, SearchActivity.class);
        startActivity(aI);
        return true;
    case R.id.action_settings:
        return true;
    case R.id.action_share:
        return true;
    }
    return super.onOptionsItemSelected(item);
}

3. actionbar in overlay mode

flower

create a custome theme

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- theme -->
    <style name="MEActionBarTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
        <item name="android:actionBarStyle">@style/MEActionBar</item>
        <item name="android:windowActionBarOverlay">true</item>
    </style>
    <!-- ActionBar styles -->
    <style name="MEActionBar" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@color/transparent_background</item>
    </style>
    <color name="transparent_background">#3b000000</color>
</resources>

declare the theme

declare the activity theme as android:theme="@style/MEActionBarTheme"

toggle actionbar via click

hook onClick() event of the view object(TextView or RelativeLayout etc.) with following code:

@Override
public void onClick(View v) {
    if (getActionBar().isShowing()) {
        getActionBar().hide();
    } else {
        getActionBar().show();
    }
}

misc

themes can be applied to Activity/Application.

eg: Theme.Holo, Theme.Holo.Light,

google has a default Action Bar Icon Pack.

Proxy - ShadowSocks (socks5)

1. set up shadowsocks server

install ss for both server and client

Debian/Ubuntu

apt-get install python-pip
pip install shadowsocks

MacOs

brew install shadowsocks-libev

start service

  • linux
    ssserver -p 123 -k <PWD> --fast-open --workers 2 -d start

or, edit /etc/shadowsocks-libev/config.json, then start as service

service shadowsocks-libev  restart

start client

  • Debian/Ubuntu

    apt-get install netcat-openbsd
    nohup sslocal –fast-open -p 123 -l 9999 -k -s <SERVER_ADDRESS>

  • MacOs

install as service

brew services start shadowsocks-libev

manual run

/usr/local/opt/shadowsocks-libev/bin/ss-local -c /usr/local/etc/shadowsocks-libev.json -u

2. start applications

2.1 setup chrome plugin

install the “proxy SwitchyOmega” plugin for chrome, set proxy to: type socks5, addr 127.0.0.1, port 9999

2.2 setup ssh

.ssh/config

host github.com
  identityfile ~/.ssh/hasee
  ProxyCommand nc -x 127.0.0.1:9999 %h %p

2.3 setup aptitude/apt-get

apt-get install tsocks

edit tsocks config /etc/tsocks.conf

server = 127.0.0.1
server_type = 5
server_port = 9999

try it out

tsocks apt-get update

2.4 setup git

proxy="SOCKS 127.0.0.1:9999" git clone xxxxx

Defend Squid3

保卫鱿鱼

现象

机器狂慢,带宽实时用量逼近threshold, VPS发警示邮件

查看log

/var/log/squid3/access.log
海量IP疯狂刷本机3128端口,

解决

1. 改变默认端口号到不常用大端口
2. 关闭open proxy, 使用密码验证
3. IP过滤

从access.log提取海量IP, 直接用iptables过滤,丢弃来自攻击网段的所有包

iptables -I INPUT -s <IP_RANGE> -j DROP
如:
iptables -I INPUT -s 90.181.203.0/24 -j DROP

结果

The world is clean and clear.

Proxy - squid3 (http)

环境 Debian 10

安装

apt install squid apache2-utils

创建密码文件

htpasswd -c  /etc/squid/squid.pwd <用户名>

配置认证程序

auth_param basic program /usr/lib/squid3/ncsa_auth /etc/squid3/squid.pwd
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours

允许密码

acl password proxy_auth REQUIRED
http_access allow password

取消deny all

#http_access deny all

问题:

1. squid3无法启动:
查看/var/log/squid3/cache.log
原则上可以把密码文件放在任何位置,但是如果放在/root下,则squid3无法访问该文件。

gradle.properties

systemProp.http.proxyHost=10.70.52.159
systemProp.http.proxyPort=3128
systemProp.http.proxyUser=linux
systemProp.http.proxyPassword=linux

systemProp.https.proxyHost=10.70.52.159
systemProp.https.proxyPort=3128
systemProp.https.proxyUser=linux
systemProp.https.proxyPassword=linux

storage_access_framework

SAF (Storage Access Framework)

1. intro

可以提供本地/云端的DocumentsProvider

Google guide https://developer.android.com/guide/topics/providers/document-provider.html

api:

prebuilts/sdk/api/19.txt

2. 系统包含3部分:

  • DocumentsProvider

    继承DocumentsProvider的类,作为provider

  • Client app

    发intent (ACTION_OPEN_DOCUMENT and/or ACTION_CREATE_DOCUMENT)

  • Picker

    一个UI,让用户选文件,系统默认有DocumentsUI.apk

3. providers

系统内置的DocumentsProvider

1. DownloadStorageProvider
2. ExternalStorageProvider
3. MediaDocumentsProvider

系统的sample provider:

4. VaultProvider

    development/samples/Vault/src/com/example/android/vault/VaultProvider.java

5. MyCloudProvider

    development/samples/browseable/StorageProvider/src/com.example.android.storageprovider/MyCloudProvider.java

6. CTS test provider

    cts/hostsidetests/appsecurity/test-apps/DocumentProvider

4. client samplese

samples/ApiDemos/src/com/example/android/apis/content/DocumentsSample.java
samples/browseable/StorageClient/src/com.example.android.storageclient

5. client实测

intent

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=org.cfig/.app.saf.SAFActivity }

NG:(image with GMS)

I/ActivityManager(  550): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=org.cfig/.app.saf.SAFActivity} from uid 0 on display 0

I/ActivityManager(  550): START u0 {act=android.intent.action.OPEN_DOCUMENT cat=[android.intent.category.OPENABLE] typ=*/* cmp=com.google.android.tv.frameworkpackagestubs/.Stubs$DocumentsStub} from uid 10066 on display 0

GOOD:(image with AOSP only)

I/ActivityManager( 1217): START u0 {flg=0x10000000 cmp=org.cfig/.app.saf.SAFActivity} from uid 0 on display 0

I/ActivityManager( 1217): START u0 {act=android.intent.action.OPEN_DOCUMENT cat=[android.intent.category.OPENABLE] typ=*/* cmp=com.android.documentsui/.DocumentsActivity} from uid 10038 on display 0

使用android.intent.action.OPEN_DOCUMENT,默认打开DocumentsUI.apk (frameworks/base/packages/DocumentsUI)

代码

int READ_REQUEST_CODE = 42;
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
intent.setPackage("com.android.documentsui");
startActivityForResult(intent, READ_REQUEST_CODE);

解释

intent.setType(): ogg files "audio/ogg",any files "*/*", imgags "image/*"
intent.setPackage(): 不设会走到GMS里面,然后会"no app to handle the intent"