Oreo以上ではバックグラウンド実行制限( https://developer.Android.com/about/versions/oreo/background )があるため、最近すべてのサービスをフォアグラウンドサービスとJobIntentServiceに置き換えました。ドキュメントによると、JobIntentServiceはAndroid 7&以下の場合はIntent Serviceのように動作し、Android 8以降の場合はJobSchedulerのように動作します。問題があることに気付きました。 Googleが提供する新しいJobIntentService。
Android 8以降:
Android 8以上で継続的にクラッシュが発生しています。同じ問題について言及されているチケットがここにありました https://issuetracker.google.com/issues/6362229 そして、私は数人のオタクが示唆する一時的な修正を追加しました。
Android 7以下:Intent Serviceのように動作するJobIntentServiceは、作業が完了すると停止しません。
ユーザーが何らかのアクションを実行するたびにトリガーされるサービス内にJobIntentServiceを実装しました。
コード
public class SampleJobIntentService extends FixedJobIntentService {
public static void postData(Context context, String data) {
Intent intent = new Intent(context, SampleJobIntentService.class);
intent.setAction(INITIAL_ACTION);
intent.putExtra(SAMPLE_ID, data);
SampleJobIntentService.enqueueWork(context,intent);
}
public static void enqueueWork(Context context, Intent work) {
SampleJobIntentService.enqueueWork(context, SampleJobIntentService.class, JOB_ID, work);
@Override
protected void onHandleWork(@NonNull Intent intent) {
if (intent != null) {
SampleRequest sampleRequest = requests.get(intent.getAction());
if (sampleRequest != null) {
try {
// perform some networking operations
} catch (Exception ex) {
Log.d("Error for intent ");
}
Log.i("send action ");
} else
Log.e("action not found for ");
}
}
}
JobIntentServiceによるクラッシュを回避するために、 https://issuetracker.google.com/issues/6362229 からいくつかの参照を取得しました
public abstract class FixedJobIntentService extends JobIntentService {
@Override
GenericWorkItem dequeueWork() {
try {
return new FixedGenericWorkItem(super.dequeueWork());
} catch (SecurityException ignored) {
doStopCurrentWork();
}
return null;
}
private class FixedGenericWorkItem implements GenericWorkItem {
final GenericWorkItem mGenericWorkItem;
FixedGenericWorkItem(GenericWorkItem genericWorkItem) {
mGenericWorkItem = genericWorkItem;
}
@Override
public Intent getIntent() {
if (mGenericWorkItem != null) {
return mGenericWorkItem.getIntent();
}
return null;
}
@Override
public void complete() {
try {
if (mGenericWorkItem != null) {
mGenericWorkItem.complete();
}
} catch (IllegalArgumentException ignored) {
doStopCurrentWork();
}
}
}
}
ええと...、それはとても大きな理論です... !!ここにすべてを置くことはできません。あなたのコンセプトを明確にするために最善を尽くします。
私は既にグーグルのドキュメントを読んで2年を失っています... _use-less
_です__no proper documentation
_と_no proper sample codes for its developers
_ .. !!それで、私は_stack-overflow
_のすべての私の投稿でこれについて言及します。他の人の時間を節約するのに役立ちます。
あなたは良いプログラマーのようです。いくつかの_hints to your posted question
_が必要です:
ヒント1:
あなた:-私は最近すべてのサービスをフォアグラウンドサービスとJobIntentServiceに置き換えました
フォアグラウンドサービス:
_ALL THE TIME RUNNING PROCESS; WHICH WILL NEVER END... ONCE IT IS STARTED
_が必要な場合は、OnStartCommand
から_START_STICKY
_を返すサービスで使用されます。いずれにしても、なんらかのコストで実装する場合と同様に使用することはお勧めしません...次に、setOngoing(true)
を使用して通知を使用する必要があります。どのエンドユーザーは通知をスワイプで削除できません。永遠にそこに残ります...
フォアグラウンドサービスの使用:
受信機にも制限がありました。上記のOreo
以降では、すべてのレシーバーとインテントアクションをマニフェストで宣言してレシーバーを作成するだけでは使用できません... BootComplete
権限を使用し、_boot_completed
_インテントを受け取る単一のreceiver
を使用することをお勧めしますOより下の場合はservice
を呼び出し、Oより上はフォアグラウンドサービスを呼び出します。次に、そのフォアグラウンドサービスからすべてのランタイムレシーバーを実装し、Ondestroyメソッドで登録解除します。私はランタイムレシーバーを実装するための公式のサンプルコードを見つけたことはありません。最後に、何ヶ月もかけて苦労してそれを正常に実装しました。
フォアグラウンドサービスを使用する場合:
ブロードキャストレシーバーを実装する場合のみ...ブロードキャストレシーバーを実装しない場合。離れてください.......
ヒント2:
あなた:-私は最近すべてのサービスをフォアグラウンドサービスと
JobIntentService
に置き換えました
**サービスの品質:**
非常に小さな作業を行っているだけ...そして終了するだけです... StopSelf()
によって終了する必要があります_...繰り返しますが、_Services can cause data-loss
_が複数回呼び出された場合...同じサービススレッドと同様に複数回実行する...サービスに多くの作業を実行させたい場合は、再度_START_STICKY
_を使用してください...しかし、これは推奨されておらず、ヒントでいつ使用するかはすでに提案しています1。
** Intentserviceの品質は次のとおりです。**
比較的長時間実行されているタスクを実行していて、_property of execution serially only
_がある場合同じintentService
を何度も呼び出すと、すべての呼び出しがqueue
に保持され、_one by one
_の終了後に_one by one
_が実行されます。上に示したように、これは実際のサービスには当てはまりません。それ自体で終了します...開発者が終了する必要はありません.. !!
**すべてのユニークな品質:**
それらがcrashed
Androidになると、アプリをクラッシュさせるので、通知せずに呼び出しを停止できます。_try-catch-exception
_から_avoid crash
_で処理する必要があります。繰り返します。 。_you are implementing threads within services
_の場合_try-catch-exception
_ _will not save your application from being crashing
_...
**次に、地獄とそれを実装する方法:**
FireBaseJobScedular
を使用します:-
EVEN ALL THE TIME RUNNING TASK
_EVEN SUPPORTED BY NON STANDARD COMPANIES
_は、vivo、mi、oppo、one + 3などのように、_stock-Android
_に変更を加え、FunTouchOs、ColorOs、OxygenOsなどの名前を付けます。GooglePlyService
のインスタンスを作成し、その中で実行します。明らかに非標準の企業も、Googleアプリがそのタスクを実行することを制限しません。Oreo
..で動作します。_Android P
_でテストした場合でも、Androidバージョン5.0をAlarmManager
タスクとして動作します。minsdk above 16
_、_target sdk 26
_を使用することをお勧めします。これは、アプリを_google play
_にアップロードする場合は必須であり、そのニュースは既に聞こえているはずです。および_compile sdk 26
_。JobService
をマニフェストにバインドし、_receive_boot_complete
_の1行のアクセス許可を使用するだけですcold boot
_および_hot boot
_でもyou can focus on actual tasks
_を最小限に抑えます。return false
_を使用してタスクが完了し、JobServiceを終了することを示すことができます。Well -CTO
企業のUNKNOwn
であり、さまざまな種類のAndroid携帯電話メーカー全体で_foreground service
_によって引き起こされる問題を経験したため、私が提案しているのはなぜですか? _Apple and ios
_なので、経験を積む必要がありました。過去18年間開発者のままで、私も今日はほとんどコード化しています...すべての開発プロジェクトとその開発戦略では、私だけが考えています。
私も修正してください...また、_
what your tasks
_とproject
については言及していませんが、_foreground service and intent-service
_で実行したいことと正確に教えてください。 。、お役に立てれば幸いです。それはあなたが望むものではなく、一般的な理論的な答えです...しかし、実際の答えを与えるために、私は正確にあなたのプロジェクトの範囲を必要とします。
インテントサービスのように機能するJobIntentServiceは、作業が完了すると停止しません
問題は、拡張クラスFixedJobIntentService dequeueWorkメソッドにあります。
以下のように変更してみてください
GenericWorkItem superValue = super.dequeueWork();
if (superValue != null) {
return new FixedGenericWorkItem(superValue);
}
return null;
JobIntentSerivceコードを見ると、作業項目プロセッサロジックは下にあります。つまり、キューに作業項目がなくなるまで、すべての項目が処理されます(つまり、項目ごとにonHandleWorkが呼び出されます)。
while ((work = dequeueWork()) != null) {
if (DEBUG) Log.d(TAG, "Processing next work: " + work);
onHandleWork(work.getIntent());
if (DEBUG) Log.d(TAG, "Completing work: " + work);
work.complete();
}
実装の問題は、最初の作業項目を処理した後、super.dequeueWork()がnullを返すことです。これは、気にせず、null値を渡して新しいFixedGenericWorkItemオブジェクトを送信するだけです。後続の呼び出しでnull値がonHandleWorkに渡されることを確認できます。
これが問題の解決に役立つことを願っています。
これだけのコードが必要だと思います。新しいクラスMyJobIntentServiceを作成し、これだけのコードを記述して、postData()を呼び出してサービスを開始します。
public class MyJobIntentService extends JobIntentService {
public static void postData(Context context, String data) {
final Intent intent = new Intent(context, MyJobIntentService.class);
intent.setAction(INITIAL_ACTION);
intent.putExtra(SAMPLE_ID, data);
enqueueWork(context, MyJobIntentService.class, 1000, intent);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Ln.d("Cancelled service");
super.onDestroy();
}
@Override
protected void onHandleWork(@NonNull Intent intent) {
if (intent != null) {
final SampleRequest sampleRequest = requests.get(intent.getAction());
if (sampleRequest != null) {
try {
// perform some networking operations
} catch (Exception ex) {
Log.d("Error for intent ");
}
Log.i("send action ");
} else {
Log.e("action not found for ");
}
}
}
}
そして、あなたのサービスをマニフェストファイルに必ず追加してください
<service
Android:name="service.MyJobIntentService"
Android:exported="false"
Android:permission="Android.permission.BIND_JOB_SERVICE" />