一个application有多个activity,某个activity中定义了thread。当按返回键时,此thread就stop了。
我想做个只要没有退出当前应用,该thread就一直running。麻烦有可解的高手帮忙解决下。  谢谢!   ^_^

解决方案 »

  1.   

    只能用service做,Activity被kill了,里面的所有的东西自然就也被kill了。
      

  2.   

    activity给finish掉,thread不一定会给干掉。只是你找不到他的引用吧了,如HandlerThread.你不quit,就会一直在。如果你要做一个thread一直running,可以在Application的onCreate方法中启动Thread.让他一直循环做事情。如果你要想用service也是可以的。它是重要的组件,但是不保证service一直运行,也许某个时刻系统就会杀掉它,那怕你把它设置成foreground service
      

  3.   

    那该怎么在退出app后stop sevice呢?  
    请指教!!!
      

  4.   

    通过AIDL实现应用与service之前的通讯,例如在service中有一个循环以保证service一直运行着例如,定义全局变量对象hasRun来判断service是否继续运行
    private boolean hasRun = true;....
    while(hasRun)
    {
    .....
    }当要结束时,通过修改hasRun=false来结束,因此需要在service中写上:public void setFinish()
    {
       hasRun = false;
    }如果楼主之前未接触过AIDL和service的话,建议先去熟悉一下。
      

  5.   

    完整流程代码如下:   package com.pb.demo;import android.app.Activity;
    import android.app.ActivityManager;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.KeyEvent;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;public class ThreadRunningDemoActivity extends Activity {
    private Button btn; @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); btn = (Button) findViewById(R.id.button1); btn.setOnClickListener(btnListener);
    } private OnClickListener btnListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
    Intent intent = new Intent();
    intent.setClass(getApplication(), SecondActivity.class);
    startActivity(intent);
    }
    }; @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
    // 杀死Application
    ActivityManager activityMgr = (ActivityManager) this
    .getSystemService(ACTIVITY_SERVICE);
    activityMgr.killBackgroundProcesses(getPackageName());
    android.os.Process.killProcess(android.os.Process.myPid());
    new MyService().stopSelf();
    /*if (getApplicationContext().stopService(new Intent(
    ThreadRunningDemoActivity.this,
                MyService.class)))
            Log.v("FirstActivity", "stopService was successful");
        else
            Log.v("FirstActivity", "stopService was unsuccessful");*/ }
    return super.onKeyDown(keyCode, event);
    }}
    package com.pb.demo;import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Handler;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;public class SecondActivity extends Activity {
    private Handler mHandler;
    private Button btn;

    int count = 10;

    TextView tv; @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.second);

    btn = (Button) findViewById(R.id.second_btn);
    tv = (TextView) findViewById(R.id.text);

    btn.setOnClickListener(btnListener);

    mHandler = new Handler();
    checkUpdate.start();
    }

    private OnClickListener btnListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
    Intent intent = new Intent();
    intent.setClass(getApplicationContext(), MyService.class);
    startService(intent);
    }
    }; private Thread checkUpdate = new Thread() {
    public void run() {
    mHandler.post(showUpdate);
    }
    }; private Runnable showUpdate = new Runnable() {
    public void run() {
    if (count >= 1) {
    tv.setText(" " + count);
    } else {
    count = 10;
    tv.setText(" " + count);
    }
    count--;
    mHandler.postDelayed(showUpdate, 1000); 
    }
    };}
    AndroidManifest.xml如下:  <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.pb.demo"
        android:versionCode="1"
        android:versionName="1.0" >    <uses-sdk android:minSdkVersion="8" />
        <uses-permission android:name="android.permission.RESTART_PACKAGES" /> 
        <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>     <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" >
            <activity
                android:name=".ThreadRunningDemoActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name=".SecondActivity"/>
            <service android:name=".MyService" android:enabled="true"/>
        </application></manifest>package com.pb.demo;import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.Handler;
    import android.os.IBinder;
    import android.text.format.Time;
    import android.util.Log;public class MyService extends Service {
    private Handler mHandler = new Handler();
    private static int count = 1;

    // 定义个一个Tag标签
    private static final String TAG = "MyService";
    // 这里定义吧一个Binder类,用在onBind()有方法里,这样Activity那边可以获取到
    private MyBinder mBinder = new MyBinder(); @Override
    public IBinder onBind(Intent intent) {
    Log.v(TAG, "start IBinder~~~");
    return mBinder;
    } @Override
    public void onCreate() {
    myThread.start();

    Log.v(TAG, "start onCreate~~~");
    super.onCreate();
    } @Override
    public void onStart(Intent intent, int startId) {
    Log.v(TAG, "start onStart~~~");
    super.onStart(intent, startId);
    } @Override
    public void onDestroy() {
    Log.v(TAG, "start onDestroy~~~");
    super.onDestroy();
    } @Override
    public boolean onUnbind(Intent intent) {
    Log.v(TAG, "start onUnbind~~~");
    return super.onUnbind(intent);
    } // 这里我写了一个获取当前时间的函数,不过没有格式化就先这么着吧
    public String getSystemTime() {
    Time t = new Time();
    t.setToNow();
    return t.toString();
    } public class MyBinder extends Binder {
    MyService getService() {
    return MyService.this;
    }
    }

    private Thread myThread = new Thread() {
    @Override
    public void run() {
    mHandler.post(updateData);
    }
    };

    private Runnable updateData = new Runnable() {
    @Override
    public void run() {
    Log.v("count", ""+count);
    count ++;
    mHandler.postDelayed(updateData, 1000);
    }
    };}
      

  6.   

    这个是我写的一个demo。start service后,我返回到第一个activity,点击返回键则退出应用app和stop service。在logcat里可看到如下情况:停顿大概3秒的时间service没有启动,3秒后service又自动启动了。此时service还是没有stop掉。麻烦知情人给解说下,谢谢!    ^_^
      

  7.   

    1.service是系统来创建的,你不要new.你要停止他,用stopService(context,MyService).
      但是如果后面有人bind或者start它,它还会起来的。而且就算你杀掉了它所在的process,一旦service启动,acvitivymanagersservice会去检测process是否已经启动,没有就先fork一个,然后在去createserice.
    2.最好不要自己去stop process. process list是系统维护的.
      

  8.   

    我注释掉的就是采用context.stopService(contenxt,Myservice.class)。还是没用。那我不去stop系统app,难道我要自定义Application类?麻烦你给指导下,谢谢!  ^_^
      

  9.   

    还没有stop掉,是你有应用还在用他吧,你要做成只要application还在,thread就一直运行的话,那就继承Application类看看。
    那这个thread就一直在跑,除非进程给杀掉。
      

  10.   

    按理说我的app应用都退出了,thread怎么还在运行呢?
      

  11.   

    你的app退出是什么概念?啥死了process吗?如果process杀死了,线程就不存在了。
    如果是指activity退出,activity是在是activitymanagerservice维护,在ActivityThread中也有一个clientrecode,如果退出了,这两个里面没有记录了,但是这个和线程没关系,线程如果里面有循环,或者有looper,就会一直在,除非自己退出,或者给杀掉
      

  12.   

    就是退出app之后,应停止service!   这个问题已解决了!  
      

  13.   

    关于onKeyDown退出系统时stopService的问题,看到你也遇到过类似的问题,不知道是怎么解决的呢?求教