我有一个JobIntentService
,它在每次推送通知进入时启动,告诉服务去获取更多数据。当应用程序处于前台时,一切都会正常进行。
当应用程序在后台并且有多个推送通知进入时,该意图被排队,并且它多次执行相同的意图,这给服务器带来了不必要的压力,因为第一次调用服务器将获得所需的所有信息使得不需要来自推送通知的其他排队意图。
是否有要取消或不向队列添加相同意图的方法,或者是否有其他方法来防止对服务器的额外调用?
答案 0 :(得分:1)
因此,首先是几个已经很相似的问题,它们具有很多很好的知识:question1和question2。也许您的问题甚至重复了类似的问题。
最干净的方法是让您进入MyOwnJobIntentService extends JobIntentService
中JobIntentService的工作队列。
在androidx.core.app.JobIntentService.java
中有:
final ArrayList<CompatWorkItem> mCompatQueue;
在您的MyOwnJobIntentService extends JobIntentService
中:
if(mCompatQueue.isEmpty()){
//only in this case enqueue new job
}
但是很遗憾,mCompatQueue
不是公共字段。
十分钟后,我们得到了一个可行的解决方案-> SingleJobIntentService
一个JobIntentService,如果已经在工作,它将不会排队。
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v4.app.JobIntentService;
import android.util.Log;
public class SingleJobIntentService extends JobIntentService {
private static final String TAG = "SingleJobIntentService";
private Intent theOnlyJobIhave = null;
public static void enqueue(Context context, Intent work) {
Log.d(TAG, "enqueue: someone tries to add me work " + work.hashCode());
JobIntentService.enqueueWork(
context,
SingleJobIntentService.class,
SingleJobIntentService.class.hashCode(),
work);
}
@Override
protected void onHandleWork(@NonNull final Intent theWorkIgot) {
Log.d(TAG, "onHandleWork: " + this.hashCode());
if (theOnlyJobIhave == null) {
theOnlyJobIhave = theWorkIgot;
final int extraValue = theOnlyJobIhave.getIntExtra(MainActivity.KEY, -500);
Log.d(TAG, "onHandleWork: " + extraValue);
try {
Thread.sleep(7000); //this simulates fetch to server
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
Log.d(TAG, "onHandleWork I'm already busy, refuse to work >:(");
}
Log.d(TAG, "onHandleWork end");
}
}
您可能想通过一个简单的按钮操作来测试它:
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends AppCompatActivity {
public static final String KEY = "KEYKEY";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
final Intent theIntent = new Intent();
theIntent.putExtra(KEY, 666);
SingleJobIntentService.enqueue(MainActivity.this, theIntent);
}
});
}
}
注意:您必须谨慎对待线程,因为我提供的解决方案不是线程安全的。例如,在 EDIT:考虑之后->因为androidx.core.app.JobIntentService.java
中,触摸mCompatQueue
是同步的。onHandleWork
是从单个线程的JobIntentService调用的没有线程问题,解决方案是线程安全的!
答案 1 :(得分:-2)
您可以对所有通知使用相同的通知ID,这样它将覆盖旧的通知,并为您提供唯一的具有最新意图的最新通知。
如果您有针对不同操作的多种通知类型,则可以创建不同的通知组,提供仅适用于特殊类型操作的意图。
还要继续清除通知组,因此一旦单击其中一个通知,您就可以清除同一组通知。