我创建的这个IntentService将在onStartCommand()和onDestroy()中显示Toasts,但不在onHandleIntent()中显示.我错过了一些关于IntentService限制的内容吗?
public class MyService extends IntentService {
private static final String TAG = "MyService";
public MyService(){
super("MyService");
}
@Override
protected void onHandleIntent(Intent intent) {
cycle();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); //This happens!
return super.onStartCommand(intent,flags,startId);
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
Toast.makeText(this, "service stopping", Toast.LENGTH_SHORT).show(); //This happens!
super.onDestroy();
}
private void cycle(){
Toast.makeText(this, "cycle done", Toast.LENGTH_SHORT).show(); //This DOESN'T happen!
Log.d(TAG,"cycle completed"); //This happens!
} …Run Code Online (Sandbox Code Playgroud) 从我所看到和阅读的内容来看,如果有人真的想要对您的软件进行逆向工程或对其进行反编译,ProGuard就不会阻止它们.但它至少是一种适度的威慑力吗?我不确定以后翻译我的堆栈跟踪是否值得.
在Google的记事本示例中,它们似乎不关闭数据库,至少不在onDestroy()中.
关闭它的目的是什么,我真的需要吗?开放数据库是否会占用大量内存?我发现在onDestroy中关闭它会留下漏洞,如果有任何运行的线程可能会在Activity完成后尝试访问它.
我已经知道,如果您的应用被应用程序杀手强制关闭,或者通过Android设置,您的待处理警报会丢失.但是如果由于内存非常低而导致Android本身死亡该怎么办呢.在这种情况下你的警报会丢失吗?这实际发生的频率是多少?
我看到两种方法可以从失去警报中恢复过来:
如果您的应用程序有主要活动,请使用onCreate()检查您的警报是否在计划之后运行(警报应该存储它最后一次在pref中运行的时间),并根据需要重新安排它.
找到一些常见的重复Android任务,以便与接收器锁定,以执行与上面相同的检查.
这两者都有一些明显的主要缺点.还有其他想法吗?
有谁知道这可能意味着什么?显然别人的应用程序导致我的崩溃?它恰好是一个直接与我竞争的应用程序:
java.lang.RuntimeException: Unable to create BackupAgent com.MY_COMPEITOR'S_APP.backup.BackupAgent: java.lang.NullPointerException
at android.app.ActivityThread.handleCreateBackupAgent(ActivityThread.java:2905)
at android.app.ActivityThread.access$4000(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2128)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.app.ActivityThread$PackageInfo.initializeJavaContextClassLoader(ActivityThread.java:529)
at android.app.ActivityThread$PackageInfo.getClassLoader(ActivityThread.java:474)
at android.app.ActivityThread.handleCreateBackupAgent(ActivityThread.java:2873)
... 10 more
Run Code Online (Sandbox Code Playgroud) 按照Googles使用服务的示例,我创建了几个这样的线程.我不能使用IntentService,因为我正在做一些涉及等待回调的事情.
但是,我不知道如何终止以这种方式启动的Thread.据我了解,Threads会在run()方法返回时自动终止.但是,这种线程没有run方法.我的线程正在泄漏 - 它们在stopSelf()之后保持活跃状态.
@Override
public void onCreate() {
HandlerThread thread = new HandlerThread("ServiceStartArguments",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
HandlerThread thread2 = new HandlerThread("CallbackHandling",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread2.start();
mServiceLooper = thread.getLooper();
mCallbackLooper = thread2.getLooper();
mServiceHandler = new MyHandler(mServiceLooper);
mCallbackHandler = new Handler(mCallbackLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish …Run Code Online (Sandbox Code Playgroud) 我正在制作动态壁纸,所以不用担心物理碰撞.我只想尽可能保持平滑的帧速率,最高可达30fps,以节省电池电量.
为此,在循环结束时,我测量自该循环开始以来的时间.如果帧花费少于33ms,我使用Thread.sleep()来休眠ms的数量,最多可达33.
但是,我知道Thread.sleep()不是非常准确,并且可能比我要求的睡眠时间更长.我不知道多少钱.
我可以使用不同的方法来提供更均匀的速率吗?
我需要一个允许重复键的 hashmap 的 kotlin 代码
class HashMap<K, V> : MutableMap<K, V>
Run Code Online (Sandbox Code Playgroud) 我有一个使用三个 LiveData 源的 MediatorLiveData。当它们中的任何一个发出一个新值并且我至少有一个值时,我使用这三个值来生成 UI 的输出。
其中两个来源是关于如何对列表进行排序和过滤的用户设置,第三个是从 Room 数据库 Flow 中提取的列表数据。
它看起来像这样:
val thingsLiveData: LiveData<List<Thing>> = object: MediatorLiveData<List<Thing>>() {
var isSettingA: Boolean = true
var settingB: MySortingEnum = MySortingEnum.Alphabetical
var data: List<Thing>? = null
init {
addSource(myRepo.thingsFlow.asLiveData()) {
data = it
dataToValue()
}
addSource(settingALiveData) {
isSettingA= it
dataToValue()
}
addSource(settingBLiveData) {
settingB= it
dataToValue()
}
}
private fun dataToValue() {
data?.let { data ->
viewModelScope.launch {
val uiList = withContext(Dispatchers.Default) {
produceUiList(data, isSettingA, settingB)
}
value = listItems
}
} …Run Code Online (Sandbox Code Playgroud) android kotlin android-room kotlin-coroutines kotlin-coroutines-flow
android ×9
kotlin ×2
android-room ×1
google-play ×1
hashmap ×1
java ×1
proguard ×1
sqlite ×1
stack-trace ×1