Android : Do Application Login in background on bo

2020-07-13 07:52发布

I have a VOIP Application, I need to login the application in background on device bootup.

Currently the init to my application is done on UI Active(onCreate()).

I have the following things in my mind, can anyone help and clear my doubts.

  1. The service design is must to achieve this task??
  2. Which Service Remote(AIDL) or Local Service and why?
  3. How does the UI and Service interaction happens?
  4. After UI is active who gets the Call- Backs? UI or Service?
  5. Should i make Service as my Controller i.e Service to UI data Pass Vice-versa?

Sample App: Skype.

5条回答
干净又极端
2楼-- · 2020-07-13 08:18

Try a service with a boot reciever. Here is an example I found after a quick google search. Then make sure to store in the login info somewhere for when the app starts. Not sure what callbacks you might have, so really hard to answer that part. I would say that if the callbacks should affect the UI then let the activity take them over when it starts up. If you need a UI when only the service is running, probably best to throw up a notification and have it call the appropriate activity with the callback data.

查看更多
Bombasti
3楼-- · 2020-07-13 08:23

If you login is takes so long use [AccountManager][1] and do it only once. The idea behind the AccountManager a token or whatever credentials you need to use in your Service.

In your particular case I think the best way of communicating your Activity with the Service is binding to it.

查看更多
Luminary・发光体
4楼-- · 2020-07-13 08:24

So there are many ways to achieve what you want, it is a matter of what fits your style and design better. Hopefully you will find this information useful.

  1. For the application to login in the background on startup there are a few option. The first thing you will need is a BroadcastReceiver which is defined as a receiver in the manifest. Have the BroadcastReceiver catch the ACTION_BOOT_COMPLETED intent. From here you can launch your Service. This leads to #2.

  2. If all you are doing are RESTful calls then really an IntentService would be ideal. The difference between an IntentService and a Service is simple: An IntentService runs off of the main thread, executes it's 'code' and dies. A Service, however runs on the main thread (this is an important fact) and is long running so it has to be told to stopSelf(). To take matters further, a Service is also less likely to be killed compared to an Activity (application components are killed to make room in memory for newly launched apps), ie. it takes higher precedence. The service can also be declared a foreground service which requires a notification but give even higher precedence. I think in your case a Service would be perfect.

  3. Once your UI (Activity) is opened the best way to connect to the Service would be the Binder. This will allow multiple interfaces to the Service from different applications / components if need be. AIDL is pretty cool stuff but from my experience much harder to manage since all parameters must be primitive or Parcables. AIDL is also slower an less efficient because it is really a form of IPC. When a Service is started with an intent the onStartCommand() method is called. If the service is started by an application trying to bind to it then the onBind() method is called. But you can start the Service with and Intent and then bind to it. If you prefer the RESTful approach where you just have quick calls for data you can use an IntentService with a ResultReceiver. This is a great article written about Google I/O examples and just overall well implemented if you are interested in the IntentService and ResultReceiver.

  4. This is up to you. Using the Binder or AIDL your Activity can call the Service methods just like object method where the 'callback' would just be the method return. If you use a ResultReceiver the Activity interfacing the Receiver would be the callback. You could also just pass Intents back and forth but this could get messy. Again for your case the Binder approach would be good as well as a Receiver.

  5. Think of the Service as a model in the MVVM system - use it as a helper to get data from, not as something that controls the logic of the application.

Sorry if this seems messy there are so many ways to achieve what you are looking for. Its just a matter of what fits your situation best what you 'feel' is better. Not to mention the Android SDK is pretty large. I tried to hit on all the topics that could help you out. Good luck!

查看更多
\"骚年 ilove
5楼-- · 2020-07-13 08:40

Best source of knowledge about basic Service usage is SDK. Long story short AIDL is used for IPC communications and as long as you run the service in the same process you don't need it. I suppose you have two options:

  1. If the only thing you need is just login, you can start a service on boot up, login and then i.e. send a sticky broadcast with bundled login data which will be then received in application. See this question for a good set of ways to start a service on boot up.

    @Override
    public void onCreate() {
        Data data = performLogin();
        Intent i = new Intent(ACTION_VOIP_LOGIN);
        i.putExtra(EXTRA_LOGIN_DATA, data);
        mContext.sendStickyBroadcast(i);
    }
    
    ...
    
    private final class LoginReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // You may use a Bundle instead
            Data data = intent.getParcelableExtra();
            processLoginData(data)
        }
    }
    
    protected void onCreate(Bundle savedInstanceState) {
         ...
         IntentFilter filter = new IntentFilter(ACTION_VOIP_LOGIN);
         mContext.registerReceiver(new LoginReceiver(), filter);
    }
    
  2. In second case you might want to move all your logic to the service. Here you'll extend the Binder class. See this SDK article for details.

查看更多
地球回转人心会变
6楼-- · 2020-07-13 08:41

you can authanticate user login by background services package com.javaorigin.android.sample.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class MyService extends Service {

   String tag="TestService";
   @Override
   public void onCreate() {
       super.onCreate();
       Toast.makeText(this, "Service created...", Toast.LENGTH_LONG).show();      
       Log.i(tag, "Service created...");
   }

   @Override
   public void onStart(Intent intent, int startId) {      
       super.onStart(intent, startId);  
       Log.i(tag, "Service started...");
   }
   @Override
   public void onDestroy() {
       super.onDestroy();
       Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
   }

   @Override
   public IBinder onBind(Intent intent) {
       return null;
   }
}


public class SampleAction extends Activity {
   @Override
   protected void onCreate(Bundle savedInstanceState) {      
       super.onCreate(savedInstanceState);
       TextView view = new TextView(this);      
       view.setText("Service Test");
       Intent i = new Intent();
       i.setClassName( "com.javaorigin.android.sample.service",
        "com.javaorigin.android.sample.service.MyService" );
       bindService( i, null, Context.BIND_AUTO_CREATE);
       this.startService(i);      
       setContentView(view);
   }
}
查看更多
登录 后发表回答