所以在android中我想让我的应用程序类成为单例.
像这样:
object MyApplication: Application(){}
Run Code Online (Sandbox Code Playgroud)
不行.在运行时抛出以下错误:
java.lang.IllegalAccessException: private com....is not accessible from class android.app.Instrumentation.
Run Code Online (Sandbox Code Playgroud)
这样做也是不可能的:
class MyApp: Application() {
private val instance_: MyApp
init{
instance_ = this
}
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree());
}
}
companion object{
fun getInstance() = instance_
}
}
Run Code Online (Sandbox Code Playgroud)
那么如何才能在我的应用程序中随处获得应用程序类的实例,MyApp.instance()而不是使用(applicationContext as MyApp).
还解释了为什么我想要这个:我在我的应用程序中有类,例如,使用上下文初始化的SharedPreference Singleton,并且作为它的单例,不能有参数.
我有这个代码示例:
class MeasureTextView: TextView {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
companion object{
val UNIT_NONE = -1
val UNIT_KG = 1
val UNIT_LB = 0
}
fun setMeasureText(number: Float, unitType: Int){
val suffix = when(unitType){
UNIT_NONE -> {
EMPTY_STRING
}
UNIT_KG -> {
KG_SUFIX
}
UNIT_LB -> {
LB_SUFIX
}
else -> …Run Code Online (Sandbox Code Playgroud) 所以我kotlin用于android,当膨胀视图时,我倾向于做以下事情:
private val recyclerView by lazy { find<RecyclerView>(R.id.recyclerView) }
Run Code Online (Sandbox Code Playgroud)
这种方法可行.但是,有一种情况会导致应用程序出错.如果这是一个片段,并且片段转到backstack,onCreateView将再次调用,并且将重新创建片段的视图层次结构.这意味着,懒惰启动的recyclerView将指出不再存在的旧视图.
解决方案是这样的:
private lateinit var recyclerView: RecyclerView
Run Code Online (Sandbox Code Playgroud)
并初始化内部的所有属性onCreateView.
我的问题是,有没有办法重置懒惰属性,以便可以再次初始化它们?我喜欢这样的事实:初始化都是在类的顶部完成的,有助于保持代码的有序性.具体问题是在这个问题中找到的:kotlin android片段后面的空循环器视图
我有这个成绩档案:
//ext.support_library_version = '24.0.0'
android {
compileSdkVersion 24
buildToolsVersion '24.0.0'
defaultConfig {
applicationId "---"
minSdkVersion 21
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
...
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试打开任何与Android相关的类时,它说我没有api24的来源,即使buildToolsVersion '24.0.0'安装了它.知道为什么吗?
我已经在Kotlin中编写了这些方法并分析了字节码:
class A {
object b {
fun doSomething() {}
}
}
Run Code Online (Sandbox Code Playgroud)
class A {
companion object b {
fun doSomething() {}
}
}
Run Code Online (Sandbox Code Playgroud)
fun doSomething() {}
Run Code Online (Sandbox Code Playgroud)
字节码结果
Test$asb,public final doSomething()ITest$Companion,public final doSomething()ITestKt,public final static doSomething()I我的问题是:
我有一个枚举类,我想在给定枚举变量的情况下返回一个枚举实例,例如findById (enum(id, color)).我该怎么办?伴侣对象?宾语?
似乎有一个真正的静态方法的唯一方法是在包级别,没有类声明.但这有点过于全球化.有没有办法通过以下方式访问它:ClassName.staticMethod,staticMethod是非常静态的.
提供有意义的包声明方法,伴随对象和对象的示例.
语境.我一直在Kotlin编码,我发现它很棒.但有时我需要做出决定:例如,一个沉重的不可变属性在java中我会声明为静态final,但在Kotlin中我发现很难"找到一个等价物".
在Kotlin中,我如何定义var具有惰性默认值的?
例如,a val会是这样的:
val toolbarColor by lazy {color(R.color.colorPrimary)}
Run Code Online (Sandbox Code Playgroud)
我想要做的是,有一些属性(toolbarColor)的默认值,我可以改变其他任何值.可能吗?
编辑:这是部分技巧.
var toolbarColor = R.color.colorPrimary
get() = color(field)
set(value){
field = value
}
Run Code Online (Sandbox Code Playgroud)
是否可以通过写作来缓解这种情况
var toolbarColor = color(R.color.colorPrimary)
set(value){
field = value
}
Run Code Online (Sandbox Code Playgroud)
以某种方式懒惰地计算默认值?目前它不起作用,因为color()需要的Context只是稍后初始化.
我目前正在我的应用程序中使用Realm,为了确保我正确管理Realm实例,我在我的基本Activity中引入了一个如下变量:
protected val realm: Realm by lazy {
Realm.getDefaultInstance()
}
Run Code Online (Sandbox Code Playgroud)
然后在onDestroy中我这样做:
override fun onDestroy() {
super.onDestroy()
realm.close()
}
Run Code Online (Sandbox Code Playgroud)
然后我意识到这是一种浪费.如果当前活动不使用领域,它将打开并立即关闭onDestroy.
所以我更新到这个:
private var usedRealm = false
protected val realm: Realm by lazy {
usedRealm = true
Realm.getDefaultInstance()
}
override fun onDestroy() {
super.onDestroy()
if (usedRealm) {
realm.close()
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法完成同样的事情,没有额外的旗帜?
好的,这个:
fun Context.quantityFromRes(id_: Int, qtt:Int, vararg format: Any) = resources.getQuantityString(id_, qtt, format)
Run Code Online (Sandbox Code Playgroud)
XML:
<plurals name="header_view">
<item quantity="one">Oh no! You just lost %1$d Point</item>
<item quantity="other">Oh no! You just lost %1$d Points</item>
</plurals>
Run Code Online (Sandbox Code Playgroud)
给出了这个错误:
"java.util.IllegalFormatConversionException: %d can't format [Ljava.lang.Object; arguments"
Run Code Online (Sandbox Code Playgroud)
明显的Java修复:
public class XmlPluralFormatter {
private XmlPluralFormatter() {
throw new IllegalStateException("You can't fuck me =(");
}
public static String getFormattedString(Context context, int stringRes, int qtt, Object... formatArgs){
return context.getResources().getQuantityString(stringRes,qtt, formatArgs);
}
public static String getFormattedString(Context context, int stringRes, int qtt){
return …Run Code Online (Sandbox Code Playgroud) 所以几个星期前我问了这个问题:recyclerview定期ui儿童更新.
今天我想用Rxjava重构那个功能.它实际上很简单,我完成以下方式:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (friend.getGameStatus().equals(GameStatus.INGAME)) {
holderOnline.startRepeatingTask();
} else {
holderOnline.stopRepeatingTask();
}
}
class MyViewHolderOnline extends RecyclerView.ViewHolder {
private Subscription subscribe;
public MyViewHolderOnline(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void startRepeatingTask() {
subscribe = Observable.interval(updateInterval, TimeUnit.MILLISECONDS)
.map(aLong -> current.getGameStatusToPrint())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override public void onCompleted() { }
@Override public void onError(Throwable e) { }
@Override
public void onNext(String gameStatusToPrint) {
gameStatus.setText(gameStatusToPrint);
}
});
}
void stopRepeatingTask() { …Run Code Online (Sandbox Code Playgroud) 所以我用过Kotlin Android Extensions,我觉得它很容易使用,非常值得.没有更多findViewById或Butterknife.Bind(...).除了一种情况外,我发现这一切都没有问题.
例如,在基类中,BaseActivity通常会有一堆视图出现在所有布局中,例如工具栏.和常见的操作changeToolbarColor(),或setToolbarTitle().
在这个简单的情况下,我不能使用Kotlin Android Extensions,因为它是一个基类,视图本身将出现在多个布局上,并且不能导入属性.在这种情况下,我只是简单地使用by lazy {find<>(...).
有没有办法用内置的Android扩展插件完成这个?
kotlin ×8
android ×7
annotations ×1
build-tools ×1
findviewbyid ×1
properties ×1
realm ×1
rx-java ×1
sdk ×1
singleton ×1
static ×1