为什么InstanceID服务自动启动,我该如何预防这种情况? [英] Why does the InstanceID service automatically start and how do I preven this?

查看:168
本文介绍了为什么InstanceID服务自动启动,我该如何预防这种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用GCM的Android应用程序。我正在关注教程,并使用一个 InstanceIDListenerService 类,我尝试以 IntentService 用户输入一些信息的订阅页面。还有一些初步的代码在这个订阅页面之前在后台的启动屏幕上发布。在我接触到SubscriptionActivity之前,SplashScreen活动中将调用 InstanceIDListenerService 构造函数(以及随后的onHandleIntent)。它为什么这样做?是否有可能自己开始一个意向服务?

I have an android application where I'm using GCM. I'm following the tutorials and using an InstanceIDListenerService class which I'm attempting to fire off as an IntentService after a "subscription" page where the user enters some information. There is also some preliminary code firing off prior to this subscription page on a splash screen behind the scenes. The InstanceIDListenerService constructor is being called (and subsequently, the onHandleIntent) in the SplashScreen activity before I even get to the SubscriptionActivity. Why is it doing this? Is it possible for an intent service to start on it's own?

我确实在 AndroidManifest.xml 文件,当我注释掉以下几行时,它不会触发实例自动创建,应用程序按预期工作(直到我需要使用当然实例...)

I do have the service registered in the AndroidManifest.xml file, and when I comment out the following lines, it does not trigger the instance to get created automatically, the app works as intended (until I need to use the instance of course...)

<service
    android:name=".service.receiver.InstanceIDListenerService"
    android:exported="false" >
    <intent-filter>
        <action android:name="com.google.android.gms.iid.InstanceID" />
    </intent-filter>
</service>

SplashScreen.java

public class SplashScreen extends Activity {

    private BroadcastReceiver dbInsertReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();
            if(bundle != null) {
                // Handle results and move to next activity, should
                // be the subscribe activity where I want the instance 
                // id listener to start.
            }
        }
    };

    private BroadcastReceiver providerXMLReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             Bundle bundle = intent.getExtras();
             if(bundle != null) {
                 // Handle results and start the next service                 
             }
         }
     }
 };

    /** Called when the activity is first created */
    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);

        setContentView(R.layout.activity_splash_screen);

        // Kick off the service download to update the provider data
        Intent intent = new Intent(this, ProviderDataService.class);
        startService(intent);
    }

    @Override
    protected void onStart() {
        super.onStart();
        registerReceiver(providerXMLReceiver, new IntentFilter(ProviderDataService.CHANNEL));
        registerReceiver(dbInsertReceiver, new IntentFilter(InternalDBService.NOTIFICATION));
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(providerXMLReceiver, new IntentFilter(ProviderDataService.CHANNEL));
    registerReceiver(dbInsertReceiver, new IntentFilter(InternalDBService.NOTIFICATION));
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(providerXMLReceiver);
        unregisterReceiver(dbInsertReceiver);
    }            

    private void moveToNextActivity(int subscriptionStatus) {
        if(subscriptionStatus == DBSchemaHelper.IS_SUBSCRIBED_NOT_RESPONDED) {
            Intent subscribeIntent = new Intent(SplashScreen.this, SubscribeActivity.class);
            startActivity(subscribeIntent);
        } else {
            // Create an Intent that will start the Menu-Activity.
            Intent mainIntent = new Intent(SplashScreen.this, MainActivity.class);
            startActivity(mainIntent);
        }

        this.finish();
    }

SubscribeActivity.java

public class SubscribeActivity extends CustomActionBarActivity {

    public static final int NO_SUBSCRIPTION_STATUS = -99;
    private DBMetaDataSource metaDao;
    private int subscribeResult;

    public SubscribeActivity() {
        metaDao = new DBMetaDataSource(this);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_subscribe);
    }    

    @Override
    protected void onStart() {
        super.onStart();
        registerReceiver(tokenResponseReceiver, new IntentFilter(InstanceIDListenerService.TAG));
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(tokenResponseReceiver, new IntentFilter(InstanceIDListenerService.TAG));
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(tokenResponseReceiver);
    }

    public void subscribeUser(View v) {
        EditText emailTextView = (EditText) findViewById(R.id.subscriptionUserEmail);
        String email = emailTextView.getText().toString();

        // This is the only place I am manually starting this service.
        // I have set a breakpoint here, but I never hit it and the service
        // starts on its own and I hit the breakpoints in the service's 
        // onHandleIntent method.
        Intent i = new Intent(this, InstanceIDListenerService.class);
        i.putExtra("email", email);
        startService(i);
    }

    public void goToNextActivity(View v) {
        // They pressed the button to NOT subscribe, so we are calling this from the
        // view rather than the intent receiver, meaning the view will not be null.
        if(v != null) {
            markUnsubscribed();
        }

        /* Create an Intent that will start the Menu-Activity. */
        Intent mainIntent = new Intent(SubscribeActivity.this, MainActivity.class);
        mainIntent.putExtra(MainActivity.SUBSCRIBE_STATUS_KEY, subscribeResult);
        startActivity(mainIntent);
    }

    private void markUnsubscribed() {
        metaDao.open(this);
        DBMeta metaData = metaDao.get();
        metaDao.update(Long.valueOf(metaData.getVersion()), metaData.getLastRunInMillis(), DBSchemaHelper.IS_SUBSCRIBED_RESPONDED_NO, null);
        metaDao.close();
    }

    private BroadcastReceiver tokenResponseReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            subscribeResult = intent.getIntExtra(InstanceIDListenerService.RESPONSE_KEY, NO_SUBSCRIPTION_STATUS);
            goToNextActivity(null);
        }
    };
}


推荐答案

当需要通过回调 InstanceIDListenerService https://developers.google.com/android/reference/com/google/android/gms/iid/InstanceIDListenerService#onTokenRefresh()rel =nofollow> onTokenRefresh() - 如果您尚未创建任何实例id令牌,那么你在第一次调用时就没有工作要做。

You shouldn't be starting a InstanceIDListenerService yourself - that is for the system to call you when you need to refresh your Instance ID tokens via a callback to onTokenRefresh() - if you haven't created any instance id tokens yet, then you'd just have no work to do on that first call.

如果您还有其他工作要做,您应该使用自己的服务。

If you have other work to do, you should use your own service.

这篇关于为什么InstanceID服务自动启动,我该如何预防这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆