Git Product home page Git Product logo

ltbel.github.io's People

Watchers

 avatar  avatar

ltbel.github.io's Issues

sh 脚本 查找端口号并kill 进程 执行文件

fileName=$1
echo "exec file $fileName"
if [ -n "$2" ] ;then 
    port="$2" 
else 
    port=8080
fi
echo "port: $port"
#根据端口号查询对应的pid
pid=$(netstat -tunlp|grep "$port" | awk '{print $7}' | awk -F"/" '{ print $1 }');

#杀掉对应的进程,如果pid不存在,则不执行
if [ -n "$pid" ] ;then
    kill  -9  $pid;
    echo "killed $pid port:$port"
else echo "pid not exist"
fi
(java -jar "$fileName" &)

rxjava

rxjava(github)

基本类型

io.reactivex.Flowable: 0..N flows, supporting Reactive-Streams and backpressure
io.reactivex.Observable: 0..N flows, no backpressure,
io.reactivex.Single: a flow of exactly 1 item or an error,
io.reactivex.Completable: a flow without items but only a completion or error signal,
io.reactivex.Maybe: a flow with no items, exactly one item or an error.

lazyFromIterable 延迟发射数据

fun <T, R> Observable<List<T>>.lazyFromIterable(mapper: (T) -> Observable<R>): Observable<Observable<R>> {
    return flatMap { list ->
        Observable.create<Observable<R>> { emitter ->
            fun emi(index: Int) {
                if (list.size > index) {
                    emitter.onNext(mapper(list[index]).doOnComplete {
                        emi(index + 1)
                    })
                } else {
                    emitter.onComplete()
                }
            }
            emi(0)
        }
    }
}

fun <T> ObservableSource<out ObservableSource<out T>>.concat(): Observable<T> {
    return Observable.concat(this)
}

NavHostFragment

引入

    <fragment
        android:id="@+id/container"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/main" />

navGraph

<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/searchFragment">

    <fragment
        android:id="@+id/searchFragment"
        android:name="com.android.example.github.ui.search.SearchFragment"
        android:label="SearchFragment" >
        <action
            android:id="@+id/showRepo"
            destination="@+id/repoFragment"
            app:destination="@id/repoFragment" />
    </fragment>
    <fragment
        android:id="@+id/repoFragment"
        android:name="com.android.example.github.ui.repo.RepoFragment"
        android:label="RepoFragment" >
        <argument
            android:name="owner"
            app:type="string" />
        <argument
            android:name="name"
            app:type="string" />
        <action
            android:id="@+id/showUser"
            app:destination="@id/userFragment" />
    </fragment>
    <fragment
        android:id="@+id/userFragment"
        android:name="com.android.example.github.ui.user.UserFragment"
        android:label="UserFragment" >
        <argument
            android:name="login"
            app:type="string" />
        <action
            android:id="@+id/showRepo"
            app:destination="@id/repoFragment" />
    </fragment>
</navigation>

切换

findNavController().navigate(SearchFragmentDirections.showRepo(repo.owner.login, repo.name))

详细文档

重启APP

val restartIntent = PendingIntent.getActivity(app, 0, Intent(app,MainActivity::class.java),PendingIntent.FLAG_ONE_SHOT);
val mgr = app.getSystemService(Context.ALARM_SERVICE) as AlarmManager
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent)

System.exit(0)

SimpleDateFormat

/**
 * yyyy-MM-dd HH:mm:ss
 */
//val defSimpleDateFormat by lazy { SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()) }

val DATE_PATTERN_DEF = "yyyy-MM-dd HH:mm:ss"

fun String.formatDate(date: Any) = getDateFormat(this).format(date)

fun String.parseDate(date: String) = getDateFormat(this).parse(date)

private val threadLocal =object :ThreadLocal<MutableMap<String, SimpleDateFormat>>(){
    override fun initialValue(): MutableMap<String, SimpleDateFormat>  = mutableMapOf()
}

private fun getDateFormat(pattern: String): SimpleDateFormat {
    return threadLocal.get().getOrPut(pattern) { SimpleDateFormat(pattern, Locale.getDefault()) }
}

sharedPreferences 封装

属性委托对象

import android.arch.lifecycle.MutableLiveData
import android.content.Context
import android.content.SharedPreferences
import com.google.gson.reflect.TypeToken
import com.App
import java.lang.reflect.Type
import kotlin.reflect.KProperty

val sharedPreferences by lazy { App.app.getSharedPreferences("generalDelegate", Context.MODE_PRIVATE) }

inline fun <reified T> sharedPreferencesDelegate(def: T?, noinline sp: () -> SharedPreferences = { sharedPreferences }) = SharedPreferencesDelegate(def, sp, type = object : TypeToken<T>() {}.type)

class SharedPreferencesDelegate<T>(val def: T?, val sp: () -> SharedPreferences = { sharedPreferences }, val type: Type) {
    private val json by lazy { gson.toJson(def) }
    operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
        val sp = sp()
        return when (type) {
            String::class.java -> sp.getString(property.name, def as String?)
            Boolean::class.java -> sp.getBoolean(property.name, def as Boolean)
            Float::class.java -> sp.getFloat(property.name, def as Float)
            Int::class.java -> sp.getInt(property.name, def as Int)
            Long::class.java -> sp.getLong(property.name, def as Long)
            else -> gson.fromJson(sp.getString(property.name, json), type)
        } as T
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
        val edit = sp().edit()
        when (type) {
            String::class.java -> edit.putString(property.name, value as String?)
            Boolean::class.java -> edit.putBoolean(property.name, value as Boolean)
            Float::class.java -> edit.putFloat(property.name, value as Float)
            Int::class.java -> edit.putInt(property.name, value as Int)
            Long::class.java -> edit.putLong(property.name, value as Long)
            else -> edit.putString(property.name, gson.toJson(value))
        }
        edit.apply()
    }
}

inline fun <reified T> liveDataDelegate(def: T?, noinline sp: () -> SharedPreferences = { sharedPreferences }) = SharedPreferencesLiveData(def, sp, type = object : TypeToken<T>() {}.type)

class SharedPreferencesLiveData<T>(val def: T?, val sp: () -> SharedPreferences = { sharedPreferences }, val type: Type) {
    private val json by lazy { gson.toJson(def) }
    private var liveData: MutableLiveData<T>? = null
    operator fun getValue(thisRef: Any?, property: KProperty<*>): MutableLiveData<T> {
        val sp = sp()
        if (liveData == null) {
            liveData = object : MutableLiveData<T>() {
                override fun setValue(value: T) {
                    val edit = sp().edit()
                    when (type) {
                        String::class.java -> edit.putString(property.name, value as String?)
                        Boolean::class.java -> edit.putBoolean(property.name, value as Boolean)
                        Float::class.java -> edit.putFloat(property.name, value as Float)
                        Int::class.java -> edit.putInt(property.name, value as Int)
                        Long::class.java -> edit.putLong(property.name, value as Long)
                        else -> edit.putString(property.name, gson.toJson(value))
                    }
                    edit.apply()
                    if (Thread.currentThread() == Looper.getMainLooper().thread) {
                        super.setValue(value)
                    } else {
                        super.postValue(value)
                    }
                }
            }
            liveData?.value = when (type) {
                String::class.java -> sp().getString(property.name, def as String?)
                Boolean::class.java -> sp().getBoolean(property.name, def as Boolean)
                Float::class.java -> sp().getFloat(property.name, def as Float)
                Int::class.java -> sp().getInt(property.name, def as Int)
                Long::class.java -> sp().getLong(property.name, def as Long)
                else -> gson.fromJson(sp().getString(property.name, json), type)
            } as T
        }
        return liveData!!
    }
}

Fragment 接受onActivityResult方法 使用fragment 自身的start方法启动

class AuthHandlerFragment : Fragment() {
        private val requestCode = 100
        var callBack: ((requestCode: Int, resultCode: Int, data: Intent?) -> Unit)? = null
        val intent :Intent = Intent("action")
        init {
            intent.putExtra("token", "token")
        }
        override fun onAttach(context: Context?) {
            super.onAttach(context)
            startActivityForResult(intent,requestCode)
        }
        override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            if (requestCode == this.requestCode) {
                callBack?.invoke(requestCode, resultCode, data)
            } else
                super.onActivityResult(requestCode, resultCode, data)
        }
    }

layer-list selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
        <color android:color="@color/transparent" />
    </item>
    <item>
        <layer-list>
            <item>
                <color android:color="@color/colorPrimary" />
            </item>
            <item android:bottom="2dp">
                <color android:color="@color/background" />
            </item>
        </layer-list>
    </item>
</selector>

gson

序列化带Expose注解的字段

@Expose
var key = "";

val gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()

序列化跳过带Expose注解的字段 (这里不想自己再去写注解声明就用了原来的)

val gson = GsonBuilder().addSerializationExclusionStrategy(object : ExclusionStrategy {
    override fun shouldSkipClass(clazz: Class<*>?): Boolean = false

    override fun shouldSkipField(f: FieldAttributes): Boolean {
        val expose = f.getAnnotation(Expose::class.java)
        return expose != null && !expose.serialize
    }
}).create()

@Expose(serialize = false,)
var key = 0;

序列化别名

@SerializedName("authed") //json 中名字为authed
Authedaaaaa

@SerializedName(value = "ret", alternate = [ "code"])
var ret: Int = 0

反序列化

inline fun <reified T> Gson.fromJson(json: String): T {
    return fromJson(json, object: TypeToken<T>() {}.type)
}

json 数字类型返回空字符串异常处理

val gson = GsonBuilder()
        .also { gb ->
            ScalarsJsonDeserializer.types.forEach { gb.registerTypeAdapter(it, ScalarsJsonDeserializer) }
        }.create()

private object ScalarsJsonDeserializer : JsonDeserializer<Any> {
    val types = arrayOf<Type>(String::class.java,
            Boolean::class.java,
            Byte::class.java,
            Char::class.java,
            Double::class.java,
            Float::class.java,
            Int::class.java,
            Long::class.java,
            Short::class.java
    )

    override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Any? {
        return try {
            when (TypeToken.get(typeOfT).rawType) {
                String::class.java -> json?.asString
                Boolean::class.java -> json?.asBoolean
                Byte::class.java -> json?.asByte
                Char::class.java -> json?.asCharacter
                Double::class.java -> json?.asDouble
                Float::class.java -> json?.asFloat
                Int::class.java -> json?.asInt
                Long::class.java -> json?.asLong
                Short::class.java -> json?.asShort
                else -> null
            }
        } catch (e: Exception) {
            null
        }
    }

}

fragment操作封装

import android.support.annotation.IdRes
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentTransaction
import android.support.v7.app.AppCompatActivity

inline fun <reified T : Fragment> AppCompatActivity.addFragment(@IdRes containerId: Int, tag: String, init: T.() -> Unit = {}): T {
    return fragment<T>(containerId, tag, init, FragmentTransaction::add)
}

inline fun <reified T : Fragment> AppCompatActivity.fragment(@IdRes containerId: Int, tag: String, init: T.() -> Unit = {}, operate: FragmentTransaction.(Int, T, String) -> FragmentTransaction): T {
    var fragment = supportFragmentManager.findFragmentByTag(tag)
    if (fragment == null) {
        fragment = T::class.java.newInstance()
        fragment.init()
        supportFragmentManager.beginTransaction().operate(containerId, fragment, tag).commit()
    }
    return fragment as T
}

CSS flex 布局

指定flex 布局

.box{
  display: flex;
  display: -webkit-flex; //webkit内核
}

flex container 和 flex item main axis cross axis

Hello

java 笔记测试

recycleview item宽度均分

class FragmentAdapter(val data: List<Pair<String, Class<out Fragment>>>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
        private var with = ViewGroup.LayoutParams.MATCH_PARENT
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
            parent.addOnLayoutChangeListener { v, left, _, right, _, _, _, _, _ ->
                val count = itemCount
                val expectWith = when (count) {
                    1 -> ViewGroup.LayoutParams.MATCH_PARENT
                    2,3 -> (right - left) / count
                    else -> (right - left) / 3
                }
                if (expectWith != with) {
                    with = expectWith
                    v.post { notifyDataSetChanged() }
                }
            }
            return object : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)) {}
        }

        override fun getItemCount(): Int {
            return data.size
        }

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            val lp = holder.itemView.layoutParams as RecyclerView.LayoutParams
            lp.width = with - lp.leftMargin - lp.rightMargin
        }
    }

git笔记

add
git add . //添加所有文件到git
git add "fileName" //添加指定文件到git
blame
git blame config.rb //显示文件每一行的修改人
branch
git branch //查看本地分支
git branch -a //查看所有分支
git branch test //创建分支
git branch test_branch HEAD^1 //创建分支
git branch test 6444ab774b//在指定ID创建标签
git branch -D test //[-d|-D]删除本地分支
checkout
git checkout master     //取出master版本的head。
git checkout -b test  //创建 并切换分支
git checkout tag_name    //在当前分支上 取出 tag_name 的版本
git checkout -- hello.rb //这条命令把hello.rb从HEAD中签出.
git checkout  master file_name //master 
git checkout  commit_id file_name  //取文件file_name在commit_id时的版本。
git checkout . //这条命令把 当前目录所有修改的文件 从HEAD中签出并且把它恢复成未修改时的样子.
git checkout -b dev/1.5.4 origin/dev/1.5.4 //从远程dev/1.5.4分支取得到本地分支/dev/1.5.4
commit
git commit -m "cmd merge" //提交修改
git commit --amend //修改commit
git commit --date 2017-6-5 //在指定时间提交修改
config
git config user.name SJJ //默认使用--local
git config --local user.name SJJ //设置user.name
git config --global user.name SJJ
git congfig --list //
clone
git clone <url> //clone文件到当前目录
git clone <url> [dir] //clone文件到指定目录
describe
git describe --tags --abbrev=0 //最近一次提交的tag
diff
git diff //查看 working directory 与 staging area 之间的差异
git diff --cached //查看 repository 与 staging area 之间的差异
git diff HEAD //查看 working directory 与 repository 之间的差异
git diff 3c68b87 --stat

fetch
git fetch origin //获取修改
gitk
 gitk --simplify-by-decoration --all
log
git log //显示提交记录直到最初的提交记录或者按q退出
git log -1 --pretty=%h //最近一次提交的 commit id
git log -1 --pretty=%ci //最近一次提交的时间
git log -1 --pretty=%ct //时间戳
merge
git merge hotfix //合并分支
mv
mkdir //创建文件夹
git mv [-v] [-f] [-n] [-k] <source> <destination> //移动或重命名文件,目录或符号链接
git mv *.html src //移动所有以.html 结尾的文件 到 src 目录下
pull
git pull origin master:master //从 origin 拉取master到本地master
push
git push origin test_branch:test_branch
git push origin --delete <branchName> //删除远程分支
rebase
git rebase origin/master
git rebase feature
git rebase master feature
git rebase --onto master wrong_branch readme-update
reflog
git reflog //显示HEAD记录
remote
git remote //查看远程仓库
git remote -v //查看远程仓库url
git remote add origin https://github.com/githug/githug //添加远程仓库
reset
git reset --hard id   //回退到指定版本 --hard 丢弃指定id 之后的所有修改
git reset --hard HEAD^ //回退一个版本
git reset --hard HEAD~1 //回退一个版本
git reset HEAD to_commit_second.rb //重置指定文件
--soft 参数将上一次的修改放入 staging area
--mixed 参数将上一次的修改放入 working directory
--hard 参数直接将上一次的修改抛弃
rev-list
git rev-list HEAD --count //获取提交次数
rm
git rm --cache "deleteme.rb" //将文件从git删除
stash
git stash //保存修改到暂存区栈
git stash list //显示暂存区列表
git stash pop //弹栈
status
git status //查看当前状态
tag
git tag //显示tag
git tag "tag_name" //创建临时标签
.gitignore
*.a //正则 匹配 忽略所有以.a 结尾的文件
!a.a //a.a文件不忽略

version.gradle

buildscript {
    apply from: 'versions.gradle'
    addRepos(repositories)
    dependencies {
        classpath deps.android_gradle_plugin

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    addRepos(repositories)
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
/**
* Shared file between builds so that they can all use the same dependencies and
* maven repositories.
**/
ext.deps = [:]
def versions = [:]
versions.arch_core = "1.1.1"
versions.room = "1.1.0"
versions.lifecycle = "1.1.1"
versions.support = "27.1.1"
versions.dagger = "2.15"
versions.junit = "4.12"
versions.espresso = "3.0.1"
versions.retrofit = "2.3.0"
versions.okhttp_logging_interceptor = "3.9.0"
versions.mockwebserver = "3.8.1"
versions.apache_commons = "2.5"
versions.mockito = "2.7.19"
versions.mockito_all = "1.10.19"
versions.dexmaker = "2.2.0"
versions.constraint_layout = "1.0.2"
versions.glide = "4.7.1"
versions.timber = "4.5.1"
versions.android_gradle_plugin = "3.1.2"
versions.rxjava2 = "2.1.3"
versions.rx_android = "2.0.1"
versions.atsl_runner = "1.0.1"
versions.atsl_rules = "1.0.1"
versions.hamcrest = "1.3"
versions.kotlin = "1.2.41"
versions.paging = "1.0.0"
versions.work = "1.0.0-alpha02"
versions.navigation = "1.0.0-alpha01"
def deps = [:]

def support = [:]
support.annotations = "com.android.support:support-annotations:$versions.support"
support.app_compat = "com.android.support:appcompat-v7:$versions.support"
support.recyclerview = "com.android.support:recyclerview-v7:$versions.support"
support.cardview = "com.android.support:cardview-v7:$versions.support"
support.design = "com.android.support:design:$versions.support"
support.v4 = "com.android.support:support-v4:$versions.support"
support.core_utils = "com.android.support:support-core-utils:$versions.support"
deps.support = support

def room = [:]
room.runtime = "android.arch.persistence.room:runtime:$versions.room"
room.compiler = "android.arch.persistence.room:compiler:$versions.room"
room.rxjava2 = "android.arch.persistence.room:rxjava2:$versions.room"
room.testing = "android.arch.persistence.room:testing:$versions.room"
deps.room = room

def lifecycle = [:]
lifecycle.runtime = "android.arch.lifecycle:runtime:$versions.lifecycle"
lifecycle.extensions = "android.arch.lifecycle:extensions:$versions.lifecycle"
lifecycle.java8 = "android.arch.lifecycle:common-java8:$versions.lifecycle"
lifecycle.compiler = "android.arch.lifecycle:compiler:$versions.lifecycle"
deps.lifecycle = lifecycle

def arch_core = [:]
arch_core.testing = "android.arch.core:core-testing:$versions.arch_core"
deps.arch_core = arch_core

def retrofit = [:]
retrofit.runtime = "com.squareup.retrofit2:retrofit:$versions.retrofit"
retrofit.gson = "com.squareup.retrofit2:converter-gson:$versions.retrofit"
retrofit.mock = "com.squareup.retrofit2:retrofit-mock:$versions.retrofit"
deps.retrofit = retrofit
deps.okhttp_logging_interceptor = "com.squareup.okhttp3:logging-interceptor:${versions.okhttp_logging_interceptor}"

def dagger = [:]
dagger.runtime = "com.google.dagger:dagger:$versions.dagger"
dagger.android = "com.google.dagger:dagger-android:$versions.dagger"
dagger.android_support = "com.google.dagger:dagger-android-support:$versions.dagger"
dagger.compiler = "com.google.dagger:dagger-compiler:$versions.dagger"
dagger.android_support_compiler = "com.google.dagger:dagger-android-processor:$versions.dagger"

deps.dagger = dagger

def espresso = [:]
espresso.core = "com.android.support.test.espresso:espresso-core:$versions.espresso"
espresso.contrib = "com.android.support.test.espresso:espresso-contrib:$versions.espresso"
espresso.intents = "com.android.support.test.espresso:espresso-intents:$versions.espresso"
deps.espresso = espresso

def atsl = [:]
atsl.runner = "com.android.support.test:runner:$versions.atsl_runner"
atsl.rules = "com.android.support.test:rules:$versions.atsl_runner"
deps.atsl = atsl

def mockito = [:]
mockito.core = "org.mockito:mockito-core:$versions.mockito"
mockito.all = "org.mockito:mockito-all:$versions.mockito_all"
deps.mockito = mockito

def kotlin = [:]
kotlin.stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jre7:$versions.kotlin"
kotlin.test = "org.jetbrains.kotlin:kotlin-test-junit:$versions.kotlin"
kotlin.plugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin"
kotlin.allopen = "org.jetbrains.kotlin:kotlin-allopen:$versions.kotlin"

deps.kotlin = kotlin
deps.paging = "android.arch.paging:runtime:$versions.paging"

def glide = [:]
glide.runtime = "com.github.bumptech.glide:glide:$versions.glide"
glide.compiler = "com.github.bumptech.glide:compiler:$versions.glide"
deps.glide = glide
deps.dexmaker = "com.linkedin.dexmaker:dexmaker-mockito:$versions.dexmaker"
deps.constraint_layout = "com.android.support.constraint:constraint-layout:$versions.constraint_layout"
deps.timber = "com.jakewharton.timber:timber:$versions.timber"
deps.junit = "junit:junit:$versions.junit"
deps.mock_web_server = "com.squareup.okhttp3:mockwebserver:$versions.mockwebserver"
deps.rxjava2 = "io.reactivex.rxjava2:rxjava:$versions.rxjava2"
deps.rx_android = "io.reactivex.rxjava2:rxandroid:$versions.rx_android"
deps.hamcrest = "org.hamcrest:hamcrest-all:$versions.hamcrest"
deps.android_gradle_plugin = "com.android.tools.build:gradle:$versions.android_gradle_plugin"
ext.deps = deps

def build_versions = [:]
build_versions.min_sdk = 14
build_versions.target_sdk = 26
build_versions.build_tools = "27.0.3"
ext.build_versions = build_versions

def work = [:]
work.runtime = "android.arch.work:work-runtime:$versions.work"
work.testing = "android.arch.work:work-testing:$versions.work"
work.firebase = "android.arch.work:work-firebase:$versions.work"
work.runtime_ktx = "android.arch.work:work-runtime-ktx:$versions.work"
deps.work = work

def navigation = [:]
navigation.runtime = "android.arch.navigation:navigation-runtime:$versions.navigation"
navigation.runtime_ktx = "android.arch.navigation:navigation-runtime-ktx:$versions.navigation"
navigation.fragment = "android.arch.navigation:navigation-fragment:$versions.navigation"
navigation.fragment_ktx = "android.arch.navigation:navigation-fragment-ktx:$versions.navigation"
navigation.safe_args_plugin = "android.arch.navigation:navigation-safe-args-gradle-plugin:$versions.navigation"
navigation.testing_ktx = "android.arch.navigation:navigation-testing-ktx:$versions.navigation"
deps.navigation = navigation

ext.deps = deps

def addRepos(RepositoryHandler handler) {
    handler.google()
    handler.jcenter()
    handler.maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}
ext.addRepos = this.&addRepos

viewmodels

import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentActivity

inline fun <reified T : ViewModel> Fragment.getModel(factory: ViewModelProvider.Factory? = null): T {
    return ViewModelProviders.of(this, factory).get(T::class.java)
}

inline fun <reified T : ViewModel> FragmentActivity.getModel(factory: ViewModelProvider.Factory? = null): T {
    return ViewModelProviders.of(this, factory).get(T::class.java)
}

分辨率 对应 dp 与 资源文件夹

资源文件夹 屏幕分辨率 类型 对应图标尺寸 屏幕密度 1dp
xhdpi  超高分辨率 1280*720 WQVGA 96*96 320 =2
hdpi   高分辨率 480*800 WVGA 72*72 240 =1.5
mdpi  中等分辨率 480*320 HVGA、VGA 48*48 160 =1
ldpi    低分辨率 320*240 QVGA 36*36 120 =0.75

dbflow

添加依赖

def dbflow_version = "4.2.4"
kapt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}"
implementation "com.github.Raizlabs.DBFlow:dbflow-kotlinextensions:${dbflow_version}"

初始化
FlowManager.init(this)

类型转换

@com.raizlabs.android.dbflow.annotation.TypeConverter
class PointListTypeConverter : TypeConverter<String, List<Point>>() {
    private val type = object : TypeToken<List<Point>>() {}.type
    override fun getDBValue(model: List<Point>?): String = gson.toJson(model)

    override fun getModelValue(data: String?): List<Point> = gson.fromJson(data, type)

}

linux操作命令笔记

ll | ls -l

查看文件或者目录权限
命令截图
文件属性 文件数 拥有者 所属的group 文件大小 建档日期 文件名
r:读取权限;w:写入权限;x:执行权限
权限一共分成3组,3个一组,分别是:所有者,所属组,其他人
第一位代表文件类型,-:普通文件,d:文件夹

OPTIONS

rxjava 自动注销

package sjj.fiction.util

import android.arch.lifecycle.Lifecycle
import android.arch.lifecycle.LifecycleObserver
import android.arch.lifecycle.OnLifecycleEvent
import io.reactivex.disposables.Disposable
import java.util.*

private val map = Collections.synchronizedMap(WeakHashMap<String, BaseLifecycleObserver>())

fun Disposable.destroy(onceKey: String? = null, lifecycle: Lifecycle) {
    lifecycle.addObserver(BaseLifecycleObserver(this, lifecycle, onceKey, Lifecycle.Event.ON_DESTROY))
}

fun Disposable.stop(onceKey: String? = null, lifecycle: Lifecycle) {
    lifecycle.addObserver(BaseLifecycleObserver(this, lifecycle, onceKey, Lifecycle.Event.ON_STOP))
}

fun Disposable.pause(onceKey: String? = null, lifecycle: Lifecycle) {
    lifecycle.addObserver(BaseLifecycleObserver(this, lifecycle, onceKey, Lifecycle.Event.ON_PAUSE))
}

class BaseLifecycleObserver(val disposable: Disposable,
                            private val lifecycle: Lifecycle,
                            private val onceKey: String? = null,
                            private val event: Lifecycle.Event = Lifecycle.Event.ON_DESTROY) : LifecycleObserver {
    init {
        if (onceKey != null) {
            val observer = map.remove(onceKey)
            map[onceKey] = this
            if (observer != null) {
                observer.disposable.dispose()
                lifecycle.removeObserver(observer)
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onStop() {
        if (event == Lifecycle.Event.ON_STOP) {
            clean()
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy() {
        if (event == Lifecycle.Event.ON_DESTROY) {
            clean()
        }
    }

    private fun clean() {
        disposable.dispose()
        if (onceKey != null)
            map.remove(onceKey)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        if (disposable.isDisposed) {
            lifecycle.removeObserver(this)
            if (onceKey != null)
                map.remove(onceKey)
        }
        if (event == Lifecycle.Event.ON_PAUSE) {
            clean()
        }
    }

}
// and fragment
class BaseActivity : AppCompatActivity() {
    fun Disposable.destroy(onceKey: String? = null) {
        destroy(onceKey, lifecycle)
    }

    fun Disposable.stop(onceKey: String? = null) {
        stop(onceKey, lifecycle)
    }

    fun Disposable.pause(onceKey: String? = null) {
        pause(onceKey, lifecycle)
    }
}
rxOfType<Any>().subscribe{

 }.destroy()

build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

def shortHash = 'git log -1 --pretty=%h'.execute([], project.rootDir).text.trim().toUpperCase()
def currentBranch = 'git symbolic-ref --short -q HEAD'.execute([], project.rootDir).text.trim()
def commitCont = 'git rev-list HEAD --count'.execute([], project.rootDir).text.trim().toInteger()
android {
    compileSdkVersion 27

    defaultConfig {
        applicationId "com.skylin.uav.v02.dev"
        minSdkVersion 16
        targetSdkVersion 27
        versionCode commitCont

        buildConfigField "Integer", "Inte_V", "VALUE"
        buildConfigField "String", "AAAA", "\"$AAA\""

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    android.applicationVariants.all { variant ->
        variant.outputs.all {
            outputFileName = "DMZ-${currentBranch}-${variant.buildType.name}(${variant.versionCode})-${variant.versionName}.apk"
        }
    }
    productFlavors{
        flavorDimensions "base", "custom"

        beta {
            dimension "base"
            versionName "2.5.3" + "($shortHash)"

            buildConfigField "boolean", "LOG", "false"
            buildConfigField "String", "API_V2", "\"$domain_release$api_v2\""
            buildConfigField "String", "API_V3", "\"$domain_release$api_v3\""

        }
        develop {
            dimension "base"
            versionName "3.0.1.0" + "($shortHash)"

            buildConfigField "boolean", "LOG", "true"
            buildConfigField "String", "API_V2", "\"$domain_devel$api_v2\""
            buildConfigField "String", "API_V3", "\"$domain_devel$api_v3\""

        }
        common {
            dimension "custom"

        }
        custom {
            dimension "custom"
        }
    }
}

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

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation "org.jetbrains.anko:anko:0.10.5"

    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'

    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation "com.squareup.retrofit2:converter-scalars:2.4.0"
    implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'

    implementation 'io.reactivex.rxjava2:rxjava:2.1.14'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
    implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0'

    implementation 'com.sjianjun:aLog:1.1.3'

    implementation 'org.osmdroid:osmdroid-android:6.0.1'
    //digi
    implementation 'org.slf4j:slf4j-api:1.7.25'
    implementation 'org.slf4j:slf4j-android:1.7.25'
    implementation 'com.digi:android-sdk-addon:3'

    kapt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}"
    implementation "com.github.Raizlabs.DBFlow:dbflow-kotlinextensions:${dbflow_version}"

    implementation 'com.blankj:utilcode:1.6.4'
    implementation 'com.sjianjun:permissionUtil:1.0.0'

}

android 备份数据库文件

File filesDir = null;
try {
    filesDir = new File(getFilesDir().getParentFile(), "databases");
    for (File file : filesDir.listFiles()) {
        Log.e(file);
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] buffer = new byte[4096];
        int len;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Base64OutputStream base64OutputStream = new Base64OutputStream(byteArrayOutputStream, Base64.DEFAULT);
        while ((len = fileInputStream.read(buffer)) != -1) {
            base64OutputStream.write(buffer, 0, len);
        }
        fileInputStream.close();

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toString().getBytes());
        Base64InputStream base64InputStream = new Base64InputStream(byteArrayInputStream, Base64.DEFAULT);
        File dbfile = new File(Environment.getExternalStorageDirectory(), "dbfile/"+file.getName());
        if (!dbfile.exists()) {
            dbfile.getParentFile().mkdirs();
            dbfile.createNewFile();
        }
        FileOutputStream fileOutputStream = new FileOutputStream(dbfile);
        while ((len = base64InputStream.read(buffer)) != -1) {
            fileOutputStream.write(buffer,0,len);
        }
        fileOutputStream.flush();
        fileOutputStream.close();

    }
} catch (Exception e) {
    Log.e("aa", e);
}

Log.e(filesDir);

nginx

重新加载配置文件

nginx -s reload

server配置示例

    server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  hishen.top;
        root         /root/github/lTBeL.github.io;

        ssl_certificate "/root/ssl/1_hishen.top_bundle.crt";
        ssl_certificate_key "/root/ssl/2_hishen.top.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location /fs/ {#小说fiction
                proxy_pass http://127.0.0.1:8080/;
                proxy_set_header Host $host:80;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

Retrofit2

依赖(按需添加)

    implementation 'com.squareup.retrofit2:retrofit:2.2.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.2.0'
    implementation 'com.squareup.okhttp3:okhttp:3.7.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.7.0'
    implementation 'com.google.code.gson:gson:2.8.0'
    implementation 'com.squareup.retrofit2:converter-scalars:2.0.0'

创建retrofit 对象

                    retrofit = new Retrofit.Builder()
                            .client(client)
                            .baseUrl(baseUrl())
                            .addConverterFactory(GsonConverterFactory.create(GsonUtilKt.getGson()))
                            .addConverterFactory(GsonStringConverterFactory.create(GsonUtilKt.getGson()))
//                .addCallAdapterFactory(new ObserveOnMainCallAdapterFactory())
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
                            .build();

client对象

private OkHttpClient client;

    {
        try {

            X509TrustManager xtm = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    X509Certificate[] x509Certificates = new X509Certificate[0];
                    return x509Certificates;
                }
            };

            SSLContext sslContext = null;
            try {
                sslContext = SSLContext.getInstance("SSL");

                sslContext.init(null, new TrustManager[]{xtm}, new SecureRandom());

            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
            HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };
            client = new OkHttpClient.Builder()
                    .connectTimeout(5, TimeUnit.SECONDS)
                    .readTimeout(5, TimeUnit.SECONDS)
                    .writeTimeout(5, TimeUnit.SECONDS)
                    .addInterceptor(new HttpLoggingInterceptor().setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE))
                    .hostnameVerifier(DO_NOT_VERIFY)
                    .sslSocketFactory(sslContext.getSocketFactory())
                    .build();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

ObserveOnMainCallAdapterFactory 没什么用

  final class ObserveOnMainCallAdapterFactory extends CallAdapter.Factory {
       final Scheduler scheduler = AndroidSchedulers.mainThread();
       final Scheduler io = Schedulers.io();

       @Override
       public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
           if (getRawType(returnType) != Observable.class) {
               return null; // Ignore non-Observable types.
           }
           // Look up the next call adapter which would otherwise be used if this one was not present.
           //noinspection unchecked returnType checked above to be Observable.
           final CallAdapter<Object, Observable<?>> delegate =
                   (CallAdapter<Object, Observable<?>>) retrofit.nextCallAdapter(this, returnType,
                           annotations);

           return new CallAdapter<Object, Object>() {
               @Override
               public Object adapt(Call<Object> call) {
                   // Delegate to get the normal Observable...
                   Observable<?> o = delegate.adapt(call);
                   // ...and change it to send notifications to the observer on the specified scheduler.
                   return o.subscribeOn(io).unsubscribeOn(io).observeOn(scheduler);
               }

               @Override
               public Type responseType() {
                   return delegate.responseType();
               }
           };
       }
   }

处理自定义注解 对象转json

public static class GsonStringConverterFactory extends Converter.Factory {

      public static GsonStringConverterFactory create() {
          return create(new Gson());
      }

      public static GsonStringConverterFactory create(Gson gson) {
          return new GsonStringConverterFactory(gson);
      }

      private final Gson gson;

      public GsonStringConverterFactory(Gson gson) {
          this.gson = gson;
      }

      @Override
      public Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
          for (Annotation annotation : annotations) {
              if (annotation instanceof Str) {
                  return new Converter<Object, String>() {
                      @Override
                      public String convert(Object value) {
                          return gson.toJson(value);
                      }
                  };
              }
          }
          return null;
      }
  }

转换16进制

/**
 * Created by sjj on 2017/9/19.
 */
fun ByteArray.toHexString(): String = map { String.format("%02X ", it) }.reduce { acc, s -> acc + " " + s }

fun ByteArray.hex(): String = map { String.format("%02X ", it) }.reduce { acc, s -> acc + s }

fun ByteArray.toHexString(start: Int, length: Int): String {
    val sb = StringBuilder()
    for (index in start until start + length) {
        sb.append(String.format("%02X ", get(index)))
    }
    return sb.toString()
}

fun Int.hex() = String.format("%02X ", this)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.