Fortnightly Tech Info - 20181203
Weekly Tech Info - 20181203 又开始咯。
改成 Fortnightly Tech Info - 20181203。
Coroutines
非常轻量级的异步解决方案。已经成功使用在我 mvvm-android 里面,代码在github上,总结在Everything about Kotlin 里。
Sign APK elegantly with Proguard
Step 1
- Create a local file under project called “keystore.properties”
PASSWORD=xxxxxxxx
ALIAS=xxxxxxx
Step 2
- In app/build.gradle
Put there lines before android {...}
def keystorePropertiesFile = rootProject.file("./keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
And refer it in signingConfigs
signingConfigs {
release {
keyAlias keystoreProperties["ALIAS"]
keyPassword keystoreProperties["PASSWORD"]
storeFile file("../key.store")
storePassword keystoreProperties["PASSWORD"]
}
debug {
}
}
Step 3
- Yes, generate your own keystore file and put it locally (e.g.”../key.store”), don't put it in git
Step 4
- Update buildTypes
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
signingConfig signingConfigs.debug
}
}
Now release is ready to go. But I want it to go with proguard
, so:
Step 5
- There is my script in proguard-rules.pro
# Remove debugging logs
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** i(...);
public static *** w(...);
public static *** e(...);
public static *** wtf(...);
}
# For Retrofit
-keep class retrofit2.** { *; }
-dontwarn retrofit2.**
-keepattributes Signature
-keepattributes Exceptions
# okio
-dontwarn okio.**
# okhttp3
-keep class okhttp3.*
-dontwarn okhttp3.**
-dontwarn com.squareup.okhttp.**
# kotlin coroutines
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
-keepclassmembernames class kotlinx.** {
volatile <fields>;
}
# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.mocoven.whatsgood.network.model.** { *; }
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
##---------------End: proguard configuration for Gson ----------
Fragment and ViewModel survive when rotating
One
- In Activity, make sure you have the code
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
Two
- In Fragment, observe viewmodel in onCreate(), and of course retainInstance = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true
setupViewModel()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel.popularData.value?.data?.let { initViews(it) }
}
private fun setupViewModel() {
viewModel = ViewModelProviders.of(this, mainViewModelFactory).get(MainViewModel::class.java)
viewModel.popularData.observe(this, Observer { response -> processResult(response = response) })
viewModel.getPopularData()
}