android application thread 一个application有多个activity,某个activity中定义了thread。当按返回键时,此thread就stop了。我想做个只要没有退出当前应用,该thread就一直running。麻烦有可解的高手帮忙解决下。 谢谢! ^_^ 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 只能用service做,Activity被kill了,里面的所有的东西自然就也被kill了。 activity给finish掉,thread不一定会给干掉。只是你找不到他的引用吧了,如HandlerThread.你不quit,就会一直在。如果你要做一个thread一直running,可以在Application的onCreate方法中启动Thread.让他一直循环做事情。如果你要想用service也是可以的。它是重要的组件,但是不保证service一直运行,也许某个时刻系统就会杀掉它,那怕你把它设置成foreground service 那该怎么在退出app后stop sevice呢? 请指教!!! 通过AIDL实现应用与service之前的通讯,例如在service中有一个循环以保证service一直运行着例如,定义全局变量对象hasRun来判断service是否继续运行private boolean hasRun = true;....while(hasRun){.....}当要结束时,通过修改hasRun=false来结束,因此需要在service中写上:public void setFinish(){ hasRun = false;}如果楼主之前未接触过AIDL和service的话,建议先去熟悉一下。 完整流程代码如下: 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); } };} 这个是我写的一个demo。start service后,我返回到第一个activity,点击返回键则退出应用app和stop service。在logcat里可看到如下情况:停顿大概3秒的时间service没有启动,3秒后service又自动启动了。此时service还是没有stop掉。麻烦知情人给解说下,谢谢! ^_^ 1.service是系统来创建的,你不要new.你要停止他,用stopService(context,MyService). 但是如果后面有人bind或者start它,它还会起来的。而且就算你杀掉了它所在的process,一旦service启动,acvitivymanagersservice会去检测process是否已经启动,没有就先fork一个,然后在去createserice.2.最好不要自己去stop process. process list是系统维护的. 我注释掉的就是采用context.stopService(contenxt,Myservice.class)。还是没用。那我不去stop系统app,难道我要自定义Application类?麻烦你给指导下,谢谢! ^_^ 还没有stop掉,是你有应用还在用他吧,你要做成只要application还在,thread就一直运行的话,那就继承Application类看看。那这个thread就一直在跑,除非进程给杀掉。 按理说我的app应用都退出了,thread怎么还在运行呢? 你的app退出是什么概念?啥死了process吗?如果process杀死了,线程就不存在了。如果是指activity退出,activity是在是activitymanagerservice维护,在ActivityThread中也有一个clientrecode,如果退出了,这两个里面没有记录了,但是这个和线程没关系,线程如果里面有循环,或者有looper,就会一直在,除非自己退出,或者给杀掉 就是退出app之后,应停止service! 这个问题已解决了! 关于onKeyDown退出系统时stopService的问题,看到你也遇到过类似的问题,不知道是怎么解决的呢?求教 小白问各位大神三个小问题 【求助】我要在win7下跟ok6410开发版进行ADB调试,我用不用重新编译sdk? 高分求问Launcher问题? android问题说难不难,说简单不简单 图表中鼠标点击显示数据的问题 设置全屏必须在setContentView之前才有效的问题? 项目中assets文件夹中有个data.xml文件! 纠结,这家公司不知道该不该去 关于provider开放部分URL 想设置ImageView点击事件 android textview 垂直居中 porting 3G
请指教!!!
private boolean hasRun = true;....
while(hasRun)
{
.....
}当要结束时,通过修改hasRun=false来结束,因此需要在service中写上:public void setFinish()
{
hasRun = false;
}如果楼主之前未接触过AIDL和service的话,建议先去熟悉一下。
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);
}
};}
但是如果后面有人bind或者start它,它还会起来的。而且就算你杀掉了它所在的process,一旦service启动,acvitivymanagersservice会去检测process是否已经启动,没有就先fork一个,然后在去createserice.
2.最好不要自己去stop process. process list是系统维护的.
那这个thread就一直在跑,除非进程给杀掉。
如果是指activity退出,activity是在是activitymanagerservice维护,在ActivityThread中也有一个clientrecode,如果退出了,这两个里面没有记录了,但是这个和线程没关系,线程如果里面有循环,或者有looper,就会一直在,除非自己退出,或者给杀掉