Alarmmanager و Broadcastreceiver بدلاً من الخدمة - هل هذا سيء؟ (نفذ الوقت)

StackOverflow https://stackoverflow.com/questions/3117350

سؤال

معلومات أساسية:

أحتاج إلى تحديث بعض البيانات من الويب ، حوالي كل ساعة أو نحو ذلك ، حتى عندما يتم إغلاق تطبيقي. يستغرق تحديث البيانات نفسها حوالي 40 ثانية إلى دقيقة واحدة. ثم يتم حفظه باعتباره قابلة للتسلسل إلى ملف. تتم قراءة هذا الملف عندما يبدأ تطبيقي.

هذا هو النهج الذي اتبعته في الوقت الحالي (عدم استخدام خدمة)

استخدم جهاز الإنذار و prochastreceiver مثل هذا:

private void set_REFRESH_DATA_Alarm(){
    mContext = Main.this;
    alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    broadcast_intent = new Intent(mContext, 
            RepeatingAlarmReceiver_REFRESH_DATA.class);
    pendingIntent = PendingIntent.getBroadcast(mContext, 0,  broadcast_intent, 0);
    // do a REFRESH every hour, starting for the first time in 30 minutes from now ...
    Calendar now = Calendar.getInstance();
    long triggerAtTime = now.getTimeInMillis()+ (1 * 30 * 60 * 1000); // starts in 30 minutes
    long repeat_alarm_every = (1 * 60 * 60 * 1000); // repeat every 60 minutes
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime, 
            repeat_alarm_every, pendingIntent);
}

لي REFERENTARARMRECEIVER_REFRESH_DATA.CLASS يعتني بتحديث البيانات من الويب:

public class RepeatingAlarmReceiver_REFRESH_DATA extends BroadcastReceiver {

    public static Context mContext;
    ConnectivityManager mConnectivity;

    @Override
    public void onReceive(Context context, Intent intent) {
        mContext = context;
        // if Network connection is OK (Wifi or Mobile) then Load data ...
        mConnectivity = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        Log.i("Hub",
                "mConnectivity.getNetworkInfo(0)="
                        + mConnectivity.getNetworkInfo(0));
        Log.i("Hub",
                "mConnectivity.getNetworkInfo(1)="
                        + mConnectivity.getNetworkInfo(1));
        if ((mConnectivity.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED)
                || (mConnectivity.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED)) {
            Log.i("Hub", "Connectivity OK ...");
            Refresh_HIST_DATA();
        } else {
            // else Show Dialog "No network connection" ...
            Log.i("Hub",
                    "No network connection for the moment... will try again later!");
        }
    }

    // =========================================================================
    private void Refresh_HIST_DATA() {
        Log.i("Hub", "Refresh_HIST_DATA()... Starting ...");
        // etc...
    }
}

في البيان لدي:

<receiver android:name="com.cousinHub.myapp.RepeatingAlarmReceiver_REFRESH_DATA" android:process=":remote" />

مشكلة :

يتم إطلاق المنبه في الوقت المحدد ويبدأ التحديث ولكن بعد حوالي 10 ثوانٍ يتوقف (مهلة):

06-25 11: 55: 05.278: WARN/ActivityManager (76): Timeout of BroadcastRecord {44bb4348 null} - requiver=android.os.binderproxy@44bcc670

06-25 11: 55: 05.278: WARN/ActivityManager (76): جهاز الاستقبال أثناء المهلة: solveInfo {44BB42C0 COM.COUSINHUB.MYAPP.REPEATINGALARMRECEIVER_REFRESH_DATA P = 0 O = 0 M = 0X0}

06-25 11: 55: 05.278: Info/Process (76): Sending Signal. PID: 819 SIG: 9

06-25 11: 55: 05.298: Info/ActivityManager (76): Process com.cousinhub.myapp: Remote (Pid 819) مات.

ملاحظة: من الغريب أن "المهلة" لا تحدث بعد حوالي 10 ثوانٍ على HTC Hero (لا يزال على Android 1.5 - API المستوى 4) ولكن جيدًا على جهاز Nexus One (2.1 -Update1)

أسئلة :

  1. لماذا هذه المهلة؟ أي طريقة سهلة لتجنب هذا؟
  2. هل قمت بإعداد برودكاسستير بشكل صحيح في هذا البيان؟ هل أحتاج إلى إضافة شيء ما (لتجنب هذه المهلة)؟
  3. هل يجب أن أذهب تمامًا للحصول على خدمة لهذا النوع من وظائف "التحديث من الويب"؟ (بالنظر إلى هذا المقال: http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-re-) إذا كانت الإجابة بنعم (يجب أن أتحول إلى خدمة): أي مقتطفات جيدة من التعليمات البرمجية/البرنامج التعليمي لهذا ...

كما هو الحال ، شكرا لمساعدتك.

ح.

هل كانت مفيدة؟

المحلول

لماذا هذه المهلة؟

أنت تعمل على موضوع التطبيق الرئيسي. لا يمكنك التشغيل على موضوع التطبيق الرئيسي لأكثر من بضع ثوان. أيضًا ، أثناء القيام بذلك ، أنت تؤذي أداء الجهاز (لأنك كذلك الجري بأولوية المقدمة) ، مثل التسبب في فقدان معدل الإطار في الألعاب أو مقاطع الفيديو.

أي طريقة سهلة لتجنب هذا؟

لا تقوم بعمل كبير (> 100 مللي ثانية) على مؤشر ترابط التطبيق الرئيسي. لديك BroadcastReceiver تفويض إلى IntentService, ، ربما أ WakefulIntentService.

هل قمت بإعداد برودكاسستير بشكل صحيح في هذا البيان؟

من فضلك من فضلك من فضلك من فضلك تخلص من android:process=:remote. أنت لا تحتاجها ، فهي لا تساعدك ، وهي مهينة للأداء للجهاز إلى أبعد من ذلك.

هل يجب أن أذهب تمامًا للحصول على خدمة لهذا النوع من وظائف "التحديث من الويب"؟ (بالنظر إلى هذا المقال: http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-re-) إذا كانت الإجابة بنعم (يجب أن أتحول إلى خدمة): أي مقتطفات جيدة من التعليمات البرمجية/البرنامج التعليمي لهذا ...

IMHO ، نعم. ثم مرة أخرى ، كتبت منشور المدونة هذا. على سبيل المثال ، انظر WakefulIntentService مشروع.

نصائح أخرى

للحصول على معلومات ، لقد جربت مع موضوع جديد وهو يعمل عندما يكون على WiFi (يستغرق حوالي 1'30 "لتحديث البيانات عندما يكون الهاتف نائمًا ، ولا يتم قتله"!

//let's try with a new separate thread ?
        new Thread(new Runnable() {
            public void run() {
                Refresh_HIST_DATA();
            }
          }).start();

ولكن ليس عندما على الهاتف المحمول (GPRS) ، حيث يتم قتله بعد حوالي 10 ثوان!

إنه حل نصف في الوقت الحالي وسأحاول حل Commonsware لنهج أنظف/أكثر استدامة ...

دعونا نرى ما إذا كان حل الخيط الجديد يعمل بشكل جيد أو كان محظوظًا (لقد اختبرت فقط خلال بضع ساعات) ...

إذا كان لدى أي شخص آخر اقتراح آخر ، فيرجى نشره.

بدلا من الموضوع. يمكنك بدء تشغيل Asynctask من طريقة استقبال البث الخاص بك onRecive (). هذا لن يمنع موضوع واجهة المستخدم. لقد فعلت نفسي في مشاريعي التي لها نفس الطبيعة ، أي يجب أن تنشر البيانات كل ساعة واحدة.

public void onReceive(Context context, Intent intent) {
        // start your Asynctask from here. which will post data in doInBackground() method
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top