আমি জানি, ইতিমধ্যে অনেকগুলি উত্তর প্রকাশিত হয়েছে, তবে সত্য - স্টার্টফোরগ্রাউন্ডসেসরিজ কোনও অ্যাপ স্তরে স্থির করা যায় না এবং আপনার এটি ব্যবহার বন্ধ করা উচিত। কনটেক্সট # স্টার্টফোরগ্রাউন্ডস সার্ভিস () বলা হওয়ার পরে 5 সেকেন্ডের মধ্যে সার্ভিস # স্টার্টফোরগ্রাউন্ড () এপিআই ব্যবহারের গুগলের পরামর্শটি কোনও অ্যাপ্লিকেশন সর্বদা করতে পারে এমন কিছু নয়।
অ্যান্ড্রয়েড একযোগে প্রচুর প্রক্রিয়া চালায় এবং এর কোনও গ্যারান্টি নেই যে লুপার আপনার টার্গেট পরিষেবাটিকে কল করবে যেটি 5 সেকেন্ডের মধ্যে স্টার্টফোরগ্রাউন্ডে () কল করার কথা। যদি আপনার টার্গেট পরিষেবাটি 5 সেকেন্ডের মধ্যে কলটি না পেয়ে থাকে তবে আপনি ভাগ্যের বাইরে এসেছেন এবং আপনার ব্যবহারকারীরা এএনআর পরিস্থিতি অনুভব করবেন। আপনার স্ট্যাক ট্রেসটিতে আপনি এরকম কিছু দেখতে পাবেন:
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{1946947 u0 ...MessageService}
main" prio=5 tid=1 Native
| group="main" sCount=1 dsCount=0 flags=1 obj=0x763e01d8 self=0x7d77814c00
| sysTid=11171 nice=-10 cgrp=default sched=0/0 handle=0x7dfe411560
| state=S schedstat=( 1337466614 103021380 2047 ) utm=106 stm=27 core=0 HZ=100
| stack=0x7fd522f000-0x7fd5231000 stackSize=8MB
| held mutexes=
#00 pc 00000000000712e0 /system/lib64/libc.so (__epoll_pwait+8)
#01 pc 00000000000141c0 /system/lib64/libutils.so (android::Looper::pollInner(int)+144)
#02 pc 000000000001408c /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+60)
#03 pc 000000000012c0d4 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44)
at android.os.MessageQueue.nativePollOnce (MessageQueue.java)
at android.os.MessageQueue.next (MessageQueue.java:326)
at android.os.Looper.loop (Looper.java:181)
at android.app.ActivityThread.main (ActivityThread.java:6981)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1445)
আমি যেমন বুঝতে পেরেছি, লুপার এখানে সারিটি বিশ্লেষণ করেছে, একটি "গালিগালাজী" খুঁজে পেয়েছিল এবং কেবল এটি হত্যা করেছিল। সিস্টেমটি এখন সুখী এবং স্বাস্থ্যকর, যদিও বিকাশকারী এবং ব্যবহারকারীরা নন, তবে যেহেতু গুগল তাদের দায়িত্বগুলি সিস্টেমে সীমাবদ্ধ রাখে, তবে কেন তারা পরবর্তী দুটি সম্পর্কে যত্ন নেবে? স্পষ্টত তারা না। তারা কি এটি আরও ভাল করতে পারে? অবশ্যই, উদাহরণস্বরূপ, তারা "অ্যাপ্লিকেশন ব্যস্ত" ডায়লগটি পরিবেশন করতে পারত, কোনও ব্যবহারকারীকে অ্যাপটির অপেক্ষায় বা হত্যা করার বিষয়ে সিদ্ধান্ত নিতে বলত, তবে কেন বিরক্ত করবেন, এটি তাদের দায়িত্ব নয়। মূল বিষয়টি হ'ল সিস্টেমটি এখন সুস্থ।
আমার পর্যবেক্ষণগুলি থেকে, এটি তুলনামূলকভাবে খুব কমই ঘটে থাকে, আমার ক্ষেত্রে 1 কে ব্যবহারকারীদের জন্য এক মাসে প্রায় 1 ক্রাশ হয়। এটি পুনরুত্পাদন করা অসম্ভব এবং এটি পুনরুত্পাদন করা হলেও স্থায়ীভাবে স্থির করার জন্য আপনার করার মতো কিছুই নেই।
"সূচনা" এর পরিবর্তে "বাঁধাই" ব্যবহার করার জন্য এই থ্রেডে একটি ভাল পরামর্শ ছিল এবং তারপরে যখন পরিষেবা প্রস্তুত থাকে, onSecorConnected প্রক্রিয়া করুন, কিন্তু আবার, এর অর্থ স্টার্টফোরগ্রাউন্ডস সার্ভিস কলগুলি একেবারেই ব্যবহার না করা।
আমি মনে করি, গুগল পক্ষ থেকে সঠিক এবং সৎ পদক্ষেপটি প্রত্যেককে বলা হবে যে স্টার্টফোরগেন্ডসার্চির কোনও ঘাটতি রয়েছে এবং এটি ব্যবহার করা উচিত নয়।
প্রশ্নটি এখনও রয়ে গেছে: পরিবর্তে কী ব্যবহার করবেন? সৌভাগ্যক্রমে আমাদের জন্য, এখন চাকরিচুলক এবং জবস সার্ভিস রয়েছে, যা অগ্রভাগ পরিষেবাগুলির জন্য আরও ভাল বিকল্প। এটি এর চেয়ে ভাল বিকল্প, কারণ:
যখন কোনও কাজ চলছে তখন সিস্টেমটি আপনার অ্যাপের পক্ষ থেকে একটি জাগ্রত রাখবে lock এই কারণে, ডিভাইসটি কাজের সময়কালের জন্য জাগ্রত থাকে তার গ্যারান্টি দেওয়ার জন্য আপনার কোনও পদক্ষেপ নেওয়ার দরকার নেই।
এর অর্থ হ'ল আপনার আর জেগে থাকাগুলি পরিচালনা করার বিষয়ে যত্ন নেওয়ার দরকার নেই এবং এ কারণেই এটি পূর্বের পরিষেবাগুলি থেকে আলাদা নয়। বাস্তবায়ন দৃষ্টিকোণ থেকে জবশেডুলার আপনার পরিষেবা নয়, এটি একটি সিস্টেমের, সম্ভবত এটি সঠিকভাবে সারিটি পরিচালনা করবে এবং গুগল কখনই তার নিজের সন্তানকে সমাপ্ত করবে না :)
স্যামসুং তাদের স্যামসাং অ্যাকসেসরি প্রোটোকল (এসএপি) এ স্টার্টফোরগ্রাউন্ডস সার্ভিস থেকে জবশেডুলার এবং জবস সার্ভিসে স্যুইচ করেছে। এটি স্মার্টওয়াচের মতো ডিভাইসগুলির ফোনের মতো হোস্টের সাথে কথা বলার প্রয়োজন হলে এটি খুব সহায়ক where যেহেতু কাজগুলি শিডিয়ুলার দ্বারা মূল থ্রেডে পোস্ট করা হয়েছে, এটি সম্ভব হয়ে ওঠে। আপনার মনে রাখা উচিত যে চাকরিটি মূল থ্রেডে চলছে এবং সমস্ত ভারী স্টাফ অন্যান্য থ্রেড এবং অ্যাসিঙ্ক কার্যগুলিতে অফলোড করে।
এই পরিষেবাটি আপনার আবেদনের মূল থ্রেডে চলমান হ্যান্ডলারের প্রতিটি আগত কাজ সম্পাদন করে। এর অর্থ হ'ল আপনাকে অবশ্যই নিজের এক্সিকিউশন লজিকটিকে আপনার পছন্দের অন্য থ্রেড / হ্যান্ডলার / অ্যাসিঙ্কটাস্কে অফলোড করতে হবে
জবশেডুলার / জবস সার্ভিসে স্যুইচ করার একমাত্র সমস্যাটি হ'ল আপনাকে পুরানো কোডটি রিফ্যাক্টর করতে হবে এবং এটি মজাদার নয়। আমি স্যামসাংয়ের নতুন এসএপি বাস্তবায়নটি ব্যবহার করতে গত দু'দিন ব্যয় করেছি। আমি আমার ক্র্যাশ প্রতিবেদনগুলি দেখব এবং ক্র্যাশগুলি আবার দেখলে আপনাকে জানাব। তাত্ত্বিকভাবে এটি হওয়া উচিত নয়, তবে সবসময় এমন বিবরণ থাকে যা আমরা সচেতন হতে পারি না।
আপডেট আপডেট
প্লে স্টোর দ্বারা আর ক্র্যাশ রিপোর্ট করা হয়নি। এর অর্থ হ'ল জবশেডুলার / জবস সার্ভিস এ জাতীয় সমস্যা নেই এবং এই মডেলটিতে স্যুইচ করা স্টার্টফোরগ্রাউন্ডসোসাইরি সমস্যাটি একবার এবং চিরতরে মুক্তি পাওয়ার জন্য সঠিক পন্থা। আমি আশা করি, গুগল / অ্যান্ড্রয়েড এটি পড়ে এবং শেষ পর্যন্ত প্রত্যেকের জন্য মন্তব্য / পরামর্শ / অফিসিয়াল গাইডেন্স প্রদান করবে।
আপডেট 2
যারা এসএপি ব্যবহার করেন এবং জিজ্ঞাসা করছেন যে কীভাবে এসএপি ভি 2 জবসোসভিয়ার ব্যবহার করে তা নীচে রয়েছে।
আপনার কাস্টম কোডে আপনাকে এসএপি শুরু করতে হবে (এটি কোটলিন):
SAAgentV2.requestAgent(App.app?.applicationContext,
MessageJobs::class.java!!.getName(), mAgentCallback)
ভিতরে কী চলছে তা দেখতে এখন আপনাকে স্যামসংয়ের কোডটি ছড়িয়ে দিতে হবে। SAAgentV2- এ অনুরোধএজেন্ট বাস্তবায়ন এবং নিম্নলিখিত লাইনটি একবার দেখুন:
SAAgentV2.d var3 = new SAAgentV2.d(var0, var1, var2);
where d defined as below
private SAAdapter d;
এখনই SAAdapter ক্লাসে যান এবং সার্ভিস সংযোগআরকিস্টেড ফাংশনটি সন্ধান করুন যা নিম্নলিখিত কলটি ব্যবহার করে কোনও কাজের শিডিউল করে:
SAJobService.scheduleSCJob(SAAdapter.this.d, var11, var14, var3, var12);
এসএজবসওয়ার্স হ'ল অ্যান্ড্রয়েড'ড জব সার্ভিসের একটি বাস্তবায়ন এবং এটিই একটি কাজের সময় নির্ধারণ করে:
private static void a(Context var0, String var1, String var2, long var3, String var5, SAPeerAgent var6) {
ComponentName var7 = new ComponentName(var0, SAJobService.class);
Builder var10;
(var10 = new Builder(a++, var7)).setOverrideDeadline(3000L);
PersistableBundle var8;
(var8 = new PersistableBundle()).putString("action", var1);
var8.putString("agentImplclass", var2);
var8.putLong("transactionId", var3);
var8.putString("agentId", var5);
if (var6 == null) {
var8.putStringArray("peerAgent", (String[])null);
} else {
List var9;
String[] var11 = new String[(var9 = var6.d()).size()];
var11 = (String[])var9.toArray(var11);
var8.putStringArray("peerAgent", var11);
}
var10.setExtras(var8);
((JobScheduler)var0.getSystemService("jobscheduler")).schedule(var10.build());
}
আপনি দেখতে পাচ্ছেন, এখানে সর্বশেষ লাইনটি এই সিস্টেম পরিষেবাটি পেতে এবং একটি কাজের সময় নির্ধারণের জন্য অ্যান্ড্রয়েড'ড জবশেডুলার ব্যবহার করে।
অনুরোধএজেন্ট কলটিতে আমরা এমজেন্টক্যালব্যাক পাস করেছি, এটি একটি কলব্যাক ফাংশন যা কোনও গুরুত্বপূর্ণ ঘটনা ঘটলে নিয়ন্ত্রণ প্রাপ্ত হবে। কলব্যাকটি আমার অ্যাপে এভাবে সংজ্ঞায়িত করা হয়েছে:
private val mAgentCallback = object : SAAgentV2.RequestAgentCallback {
override fun onAgentAvailable(agent: SAAgentV2) {
mMessageService = agent as? MessageJobs
App.d(Accounts.TAG, "Agent " + agent)
}
override fun onError(errorCode: Int, message: String) {
App.d(Accounts.TAG, "Agent initialization error: $errorCode. ErrorMsg: $message")
}
}
ম্যাসেজজবস এখানে একটি শ্রেণি যা আমি স্যামসুং স্মার্টওয়াচ থেকে আসা সমস্ত অনুরোধগুলি প্রক্রিয়া করতে প্রয়োগ করেছি। এটি সম্পূর্ণ কোড নয়, কেবল একটি কঙ্কাল:
class MessageJobs (context:Context) : SAAgentV2(SERVICETAG, context, MessageSocket::class.java) {
public fun release () {
}
override fun onServiceConnectionResponse(p0: SAPeerAgent?, p1: SASocket?, p2: Int) {
super.onServiceConnectionResponse(p0, p1, p2)
App.d(TAG, "conn resp " + p1?.javaClass?.name + p2)
}
override fun onAuthenticationResponse(p0: SAPeerAgent?, p1: SAAuthenticationToken?, p2: Int) {
super.onAuthenticationResponse(p0, p1, p2)
App.d(TAG, "Auth " + p1.toString())
}
override protected fun onServiceConnectionRequested(agent: SAPeerAgent) {
}
}
override fun onFindPeerAgentsResponse(peerAgents: Array<SAPeerAgent>?, result: Int) {
}
override fun onError(peerAgent: SAPeerAgent?, errorMessage: String?, errorCode: Int) {
super.onError(peerAgent, errorMessage, errorCode)
}
override fun onPeerAgentsUpdated(peerAgents: Array<SAPeerAgent>?, result: Int) {
}
}
যেমন আপনি দেখতে পাচ্ছেন, মেসেজজবসের জন্য মেসেজসকেট ক্লাসেরও প্রয়োজন রয়েছে যে আপনাকে প্রয়োগ করতে হবে এবং এটি আপনার ডিভাইস থেকে আসা সমস্ত বার্তাগুলি প্রক্রিয়া করে।
নীচের লাইন, এটি এত সহজ নয় এবং এর জন্য কিছু অভ্যন্তরীণ এবং কোডিংয়ের জন্য খনন করা দরকার তবে এটি কাজ করে এবং সর্বাগ্রে গুরুত্বপূর্ণ - এটি ক্রাশ হয় না।