Android Service如何关闭Activity

时间:2021-01-17 23:51:41
今天在编写Android程序的时候,遇到这个问题。通过百度和google的搜索结果,总结出以下方法:
方法一:
public class mService extends Service {
    //保存在service中的Activity对象
    private static mActivity m;
    //启动服务
    static void startservice(Context c){
        m=(mActivity)c;
        Intent iService=new Intent(c,mService.class);
        iService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        c.startService(iService);
    }
    //关闭服务
    static void stopservice(Context c){
        Intent iService=new Intent(c,mService.class);
        iService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        c.stopService(iService);
    }
    ……
    //在mService中关闭mActivity
    m.finish();
}
    
public class mActivity extends Activity {

    // private MediaPlayer mMPlayer;
    /*
     * (non-Javadoc)
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        ……
        //启动mService
        mService.startservice(mActivity.this);
         ……
        //停止mService
        mService.stopservice(mActivity.this);
        
    }
}

方法二:
主要包括3部分
1. 定义application类,这个类可以保存获取activity实例,记得manifest中加入android:name=".MyApp"
public class MyApp extends Application{
        private MyServiceActivity myActivity;
        
        public void setInstance(MyServiceActivity instance){
                myActivity = instance;
        }
        
        public MyServiceActivity getInstance(){
                return myActivity;
        }
}
2. 在activity中保存实例       
public class MyServiceActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((MyApp)getApplication()).setInstance(this);
    ……
    }
}
3. 在service中取回实例
public class MyService extends Service {
        MyServiceActivity myActivity;
        @Override 
        public void onCreate() {
                super.onCreate();
                setForeground(true);
                android.os.Debug.waitForDebugger();
                myActivity = ((MyApp)getApplication()).getInstance();
                ……
       }
}

我试过第一个方法,可行的。
但是当遇到AIDL的时候,恐怕就不能用这两种方法关闭Service启动的Activity了。我试过很多办法都是失败的,比如我把Activity赋值给一个静态的变量,不管怎么传值,在AIDL调用的方法中该变量就是Null。查看相关资料后,我的理解是AIDL不支持静态参数,也就说在AIDL中调用任何静态参数都是NULL。这也仅仅是我的理解,可能有错误!希望高手及时指正!
当时我的需求是这样的,一个客户端要通过我的AIDL不断地发请求打开页面,因此我需要在Service中开启一个线程,当有新的请求发过来的时候我打开页面。之前写的程序要么就是打开一个页面之后死活都不动了,要么就是不停地开启一个新的Activity,然后按back键要退掉很多的Activity,而且关闭所有的Activity之后,Service打开的新Activity又是死活不变换了。因此我需要Service打开新的页面的时候,把上一个Activity finish掉。尝试很多方法无果之后,只能用广播了,我用Service发一个广播,然后Activity接受到广播之后关闭。但是这样又出来另外个问题,广播都是一个类继承BroadcastReceive,这个类怎么去关闭Activity呢?因此只能把广播写在Acivity中了。代码如下:public class AnHTTPTool extends Activity {private WebView mWebView;private Context context;private String mTrafficID;private String mUrl;private String mAPN;private long mRas2Ftp;private long mIntervalTime;private int mTimes;private AnHTTPTool aht;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {    //启动mService    HTTPManagerService.startservice(AnHTTPTool.this);        super.onCreate(savedInstanceState);        setContentView(R.layout.browser);        aht = this;        mTrafficID = getIntent().getStringExtra("mTrafficID");mUrl = getIntent().getStringExtra("mUrl");mAPN = getIntent().getStringExtra("mAPN");mRas2Ftp = getIntent().getLongExtra("mRas2Ftp", 0);mIntervalTime = getIntent().getLongExtra("mIntervalTime", 0);mTimes = getIntent().getIntExtra("mTimes", 1);mWebView = (WebView) findViewById(R.id.WebView01);mWebView.loadUrl(mUrl);
WebSettings mWebSettings = mWebView.getSettings();MyWebViewClient mWebViewClient = new MyWebViewClient();mWebView.setWebViewClient(mWebViewClient);// 增加一个Intent过滤,添加Receiver监听service发送的广播          IntentFilter filter = new IntentFilter();          filter.addAction("Broadcast one!");          registerReceiver(mReceiver, filter);     }        protected BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubString action = intent.getAction();              if(action.equals("Broadcast one!")){                    aht.finish();                //your code here              }  }};}
class MyWebViewClient extends WebViewClient {
// 网页开始加载@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {// TODO Auto-generated method stubLog.d("H3c", "PageStarted");super.onPageStarted(view, url, favicon);}
// 网页结束加载@Overridepublic void onPageFinished(WebView view, String url) {// TODO Auto-generated method stubLog.d("H3c", "PageFinished");super.onPageFinished(view, url);}
// 在WebView中打开新的网页@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {// TODO Auto-generated method stubview.loadUrl(url);return true;}}
这样在Service中用:Intent i = new Intent("Broadcast one!");  //发送广播  context.sendBroadcast(i);  就可以结束掉打开的Activity了!

在程序结束的时候记得注销广播:

unregisterReceiver(mReceiver);