5

我有一个VOIP应用程序,我需要在设备启动时在后台登录应用程序。

目前,我的应用程序的初始化是在UIActive( onCreate()) 上完成的。

我脑子里有以下几点,任何人都可以帮助并消除我的疑虑。

  1. 服务设计是必须要完成这个任务的??
  2. 哪个Service Remote(AIDL)或本地服务,为什么?
  3. UI和交互是如何Service发生的?
  4. 活动后UI谁得到回调?UI还是Service
  5. 我应该将数据Service作为我的Controllerie ,反之亦然吗?ServiceUI

示例应用程序:Skype。

4

5 回答 5

5

所以有很多方法可以实现你想要的,关键是什么更适合你的风格和设计。希望您会发现这些信息很有用。

  1. 对于在启动时在后台登录的应用程序,有几个选项。您需要的第一件事是广播接收器,它在清单中定义为接收器。让 BroadcastReceiver 捕获ACTION_BOOT_COMPLETED意图。从这里您可以启动您的服务。这导致#2。

  2. 如果您所做的只是 RESTful 调用,那么真正的 IntentService 将是理想的。IntentServiceService之间的区别很简单:IntentService 在主线程之外运行,执行它的“代码”并死掉。然而,服务在主线程上运行(这是一个重要的事实)并且运行时间很长,因此必须告诉它stopSelf()。更进一步来说,与 Activity 相比,Service 也不太可能被杀死(应用程序组件被杀死以在内存中为新启动的应用程序腾出空间),即。它具有更高的优先级。该服务也可以声明为需要通知但给予更高优先级的前台服务。我认为在您的情况下,服务将是完美的。

  3. 一旦您的 UI(活动)打开,连接到服务的最佳方式将是Binder。如果需要,这将允许从不同的应用程序/组件到服务的多个接口。AIDL 是很酷的东西,但根据我的经验,管理起来要困难得多,因为所有参数都必须是原始参数或 Parcables。AIDL 也较慢且效率较低,因为它实际上是 IPC 的一种形式。当服务启动时,会调用 onStartCommand() 方法。如果服务由试图绑定到它的应用程序启动,则调用 onBind() 方法。但是您可以使用和 Intent 启动服务,然后绑定到它。如果您更喜欢 RESTful 方法,您可以快速调用数据,您可以将 IntentService 与ResultReceiver一起使用。 这是一篇关于 Google I/O 示例的精彩文章,如果您对 IntentService 和 ResultReceiver 感兴趣,那么总体上实现得很好。

  4. 这取决于你。使用 Binder 或 AIDL,您的 Activity 可以像对象方法一样调用服务方法,其中“回调”只是方法返回。如果您使用 ResultReceiver,则与 Receiver 交互的 Activity 将是回调。您也可以来回传递 Intent,但这可能会变得混乱。同样对于您的情况,Binder 方法和接收器一样好。

  5. 将服务视为 MVVM 系统中的模型 - 将其用作从中获取数据的助手,而不是控制应用程序逻辑的东西。

抱歉,如果这看起来很混乱,有很多方法可以实现您正在寻找的东西。这只是最适合您的情况的问题,您“感觉”更好。更不用说 Android SDK 是相当大的。我试图找到所有可以帮助你的话题。祝你好运!

于 2012-05-07T04:49:57.770 回答
1

尝试使用引导接收器的服务。 这是我在快速谷歌搜索后找到的一个例子。然后确保将登录信息存储在应用程序启动时的某处。不知道你可能有什么回调,所以很难回答那部分。我会说,如果回调应该影响 UI,那么让活动在启动时接管它们。如果仅在服务运行时需要 UI,最好抛出通知并让它使用回调数据调用适当的活动。

于 2012-04-30T13:04:38.503 回答
0

您可以通过后台服务包 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);
   }
}
于 2012-04-26T10:32:48.123 回答
0

如果您登录需要很长时间[AccountManager][1],并且只执行一次。AccountManager令牌背后的想法或您需要在Service.

在您的特定情况下,我认为与您沟通的最佳方式Activity是对其Service具有约束力。

于 2012-05-03T23:06:22.790 回答
0

有关基本Service用法的最佳知识来源是SDK。长话短说AIDL用于 IPC 通信,只要您在同一进程中运行服务,您就不需要它。我想你有两个选择:

  1. 如果您只需要登录,您可以在启动时启动服务,登录,然后发送带有捆绑登录数据的粘性广播,然后在应用程序中接收。有关在启动时启动服务的一组好方法,请参阅此问题。

    @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. 在第二种情况下,您可能希望将所有逻辑移至服务。在这里,您将扩展Binder该类。有关详细信息,请参阅此SDK 文章

于 2012-05-05T06:38:21.313 回答