【问题标题】:how to start different activities with one background service如何使用一个后台服务启动不同的活动
【发布时间】:2012-06-29 03:01:08
【问题描述】:

我是 Android 新手,遇到了一个概念问题。 我有一个包含多个活动的应用程序,其中一些活动很关键,需要用户登录 web 应用程序。

当用户单击按钮以达到其中一项关键活动时,我会调用后台服务,询问用户是否仍连接到 webApp(不是超时)。如果用户已登录,则启动活动,否则会弹出一个对话框并询问用户名和密码。问题是有几个受保护的活动,我想使用相同的服务进行验证。我目前的做法很有效,但有点笨拙。

    public class A_Activity extends Activity {
    Context context;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getApplicationContext();
        setButtonClickListener();
    }

    private void setButtonClickListener() {

        button_1 = (Button)findViewById(R.id.button1);
        button_1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {       
                Intent intentCall = new Intent(context,com.them.cp.ConnexionManagerService.class);
                intentCall.putExtra("WHO_IS_CALLED","FIRST_ACTIVITY");
                context.startService(intentCall);                   
            }
        });

        button_2 = (Button)findViewById(R.id.button2);
        button_2.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent intentCall = new Intent(context,com.them.cp.ConnexionManagerService.class);
                intentCall.putExtra("WHO_IS_CALLED","SECOND_ACTIVITY");
                context.startService(intentCall);       
            }
        });
    }
}

还有我的服务

    public class ConnexionManagerService extends Service{
    public class IsConnectedAsync extends AsyncTask<String , Void, Void>{
        protected Void doInBackground(String... whoIsCalled) {
            String redirectedURL = getRedirectedURL();
            if(redirectedURL.equalsIgnoreCase(IF_NOT_CONNECTED_URL)){
                if(whoIsCalled[0].equalsIgnoreCase("FIRST_ACTIVITY")){
                    Intent trueIntent = new Intent(getBaseContext(), FirstActivity.class);
                    trueIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplication().startActivity(trueIntent);
                }
                else if(whoIsCalled[0].equalsIgnoreCase("SECOND_ACTIVITY")){
                    Intent trueIntent = new Intent(getBaseContext(), SecondActivity.class);
                    trueIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplication().startActivity(trueIntent);
                }       
            }
            else{
                Intent falseIntent = new Intent(getBaseContext(), PopUpLoginActivity.class);
                falseIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                getApplication().startActivity(falseIntent);
            }
        }
        return null;
    }
     }

     @Override
     public void onCreate() {
    Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
    Log.d("service onCreate", "onCreate");
     }

     public int onStartCommand(Intent intent, int flags, int startId){
    String whoIsCalled = intent.getStringExtra("WHO_IS_CALLED");
    new IsConnectedAsync().execute(whoIsCalled);        
    return START_STICKY;
     }

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

据我所知,我希望我可以发送一个意图,但似乎不可能,因为它不是 UI 线程。

我的问题是:我该怎么做才能使这项服务更通用?

【问题讨论】:

    标签: android service asynchronous android-activity


    【解决方案1】:

    我想使用相同的服务进行验证。

    如果您不销毁服务,它将是同一个服务对象。如果启动服务的活动完成或停止服务,如果它是启动服务的唯一活动,它可能会被破坏。如果您想确保服务在后台提醒您在您的应用程序类(扩展应用程序)和您需要的每个活动中启动它。当 Activity 停止服务或完成服务时,服务不会被销毁,因为您的应用程序类仍处于连接状态。

    编辑:

    为了避免一次又一次地写putExtra:

    public class StartOrder1 extends Intent {
    
         public StartOrder(Context ctx, String activity_name){
               super(ctx, ServiceName.class);
               if(activity_name != null)
                    super.putExtra("WHO", activity_name);
               else
                    super.putExtra("WHO", "UNKNOWN");
         }
    
         public String getWho(){
               reurn.getIntExtra("WHO");
         }
    }
    

    启动它:

    this.startService(new StartOrder1(this, "My activity name"));
    

    最佳解决方案:

    public class StartOrder2 extends Intent {
    
         public StartOrder(Activity a){
               super(a, ServiceName.class);
               super.putExtra("WHO", a.toString());
         }
    
         public String getWho(){
               reurn.getIntExtra("WHO");
         }
    }
    

    您可以在每个 Activity 中重写 toString 方法,传递活动名称、类名,无论您想要什么。然后当你开始一个意图时:

    this.startService(new StartOrder2(this));
    

    或使用此实用程序扩展 Activity:

    public class EnhancedActivity extends Activity{
    
         protected startMyService(String name){
              Intent i = new Intent(this, MyService.class);
              i.putExtra("who", name);
              startService(i);
         }
    }
    

    并在你的最后一个活动中调用它

    [...]
    super.startMyService("activity_name");
    [...]
    

    【讨论】:

    • 谢谢你的回答,我知道它会是同一个服务对象。让我澄清一下我的问题。我想知道如何改进代码,以便能够在参数中传递一些东西,以便能够在不传递 WHO_IS_CALLED 的情况下使用它
    • ...好吧,如果您不想添加这些信息,只需制作您的海关意向。
    • 感谢您的回答,对我帮助很大。但我终于找到了一种通过使用片段来简化我正在做的事情的方法,这使我的活动架构更加高效。
    最近更新 更多