Android 更新后台运行的服务
我需要执行这样一个程序:Android 更新后台运行的服务,android,android-intent,android-service,android-broadcast,Android,Android Intent,Android Service,Android Broadcast,我需要执行这样一个程序: 启动后台服务 使用参数更新服务(从UI-用户输入) 活动结束后,服务应继续运行,并每分钟向HTTP服务器发出请求。在这个阶段中,我仍然需要在第二阶段中更新的参数——我将它们发送到服务器 该服务应该存储服务器的最后一个响应,并用最后一个响应对每个响应进行压缩。如果有更改,请通知用户 最后,当活动再次启动时,服务应使用最新的服务器响应更新UI 我尝试的是: BroadcastReceiver-问题在于OnReceive结束了所有未声明为final的参数后,将清除这些参数,而
谢谢。听起来您需要做的是能够“绑定”到您的服务。我在下面发布了一个简单的模板,说明了如何做到这一点。出于您的目的,您需要在服务类中存储变量并创建getter,以便在重新启动活动时可以获得最新的变量。另外-请注意,我在onResume和onPause中启动和停止下面的服务示例。毫无疑问,你会想用不同的方式来做这件事
//Activity
//Bind to Service Example
public class ExampleActivity extends Activity implements OnClickListener {
// UI
private Button binderButton;
// service
private MyService myService;
private Intent serviceIntent;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
// binder button
binderButton = (Button) findViewById(R.id.button1);
binderButton.setOnClickListener(this);
binderButton.setText("start");
serviceIntent = new Intent(this, MyService.class);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myService = ((MyService.MyBinder) service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
myService = null;
}
};
@Override
protected void onResume() {
super.onResume();
// start the service
startService(serviceIntent);
// bind to the service
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
// call method within the service
myService.doServiceStuff();
break;
}
}
@Override
protected void onPause() {
super.onPause();
stopService(serviceIntent);
unbindService(serviceConnection);
}
}
//服务
公共类MyService扩展服务{
专用最终IBinder活页夹=新的MyBinder();
@凌驾
公共IBinder onBind(意图arg0){
返回活页夹;
}
公共无效doServiceStuff(){
task.execute();
}
//创建一个内部活页夹类
公共类MyBinder扩展了Binder{
公共MyService getService(){
返回MyService.this;
}
}
AsyncTask任务=新建AsyncTask(){
@凌驾
受保护的Void doInBackground(Void…参数){
Log.d(“yourTag”,“长时间运行的服务任务”);
返回null;
}
};
}
谢谢javaJoe,虽然你的回答没有解决我的问题,但给了我一些好主意
我所做的:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Set Service Intent
serviceIntent = new Intent(this, UpdateService.class);
if (isMyServiceRunning()) {
//Bind to the service
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}else{
updateService=new UpdateService();
//Start the service
startService(serviceIntent);
//Bind to the service
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
}
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (UpdateService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
updateService = ((UpdateService.MyBinder) service).getService();
//Set Initial Args
updateService.setParams(int arg0);
}
@Override
public void onServiceDisconnected(ComponentName name) {
updateService = null;
}
};
@Override
protected void onDestroy() {
//UnBind from service
unbindService(serviceConnection);
//Stop Service
stopService(serviceIntent);
//Prepare intent to broadcast reciver
Intent intent = new Intent(MainActivity.this,ServiceRunnerBCR.class);
intent.setAction(ServiceRunnerBCR.ACTION_SET_UpdateService);
intent.putExtra(ServiceRunnerBCR.keyVal_arg0, arg0);
intent.putExtra(ServiceRunnerBCR.keyVal_arg1, arg1);
//Send broadcast to start UpdateService after the activity ended
sendBroadcast(intent);
super.onStop();
}
广播接收器:
public class ServiceRunnerBCR extends BroadcastReceiver {
public static final String ACTION_SET_UpdateService = "ACTION_ALARM";
public static final String keyVal_arg0="ARG0";
public static final String keyVal_arg1="ARG1";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_SET_UpdateService)){
updateIntent(context, intent.getDoubleExtra(keyVal_arg0, 0.02), intent.getStringExtra(keyVal_arg1));
}
}
private void updateIntent(Context context, double arg0, String arg1){
Intent intent = new Intent(context,UpdateService.class);
intent.setAction(ACTION_SET_UpdateService);
intent.putExtra(keyVal_arg0, arg0);
intent.putExtra(keyVal_arg1, arg1);
synchronized (this){
try {
this.wait(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
context.startService(intent);
Log.d("OREN","ServiceRunner");
}
}
服务:
public class UpdateService extends Service {
private final IBinder binder = new MyBinder();
public static final String keyVal_arg0="ARG0";
public static final String keyVal_arg1="ARG1";
private Timer timer;
private HTTPHandler http = new HTTPHandler();
private int test=0;
double arg0=0;
String arg1= "";
private TimerTask updateTask = new TimerTask() {
@Override
public void run() {
test++;
Log.d("OREN", "Timer task doing work " + test + " arg0: " + arg0);
//Do some work here
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent!=null){
arg0=intent.getDoubleExtra(keyVal_arg0, 0.002);
arg1=intent.getStringExtra(keyVal_arg1);
timer = new Timer("UpdateTimer");
timer.schedule(updateTask, 1000L, 10 * 1000L);
Log.d("OREN", "ServiceStarted" + test);
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
Log.d("OREN", "OnBind" + test);
return binder;
}
public void setArg0(double d){
arg0=d;
}
// create an inner Binder class
public class MyBinder extends Binder {
public UpdateService getService() {
return UpdateService.this;
}
}
@Override
public void onDestroy() {
Log.d("OREN", "OnDestroy" + test);
super.onDestroy();
}
@Override
public boolean onUnbind(Intent intent) {
Log.d("OREN", "OnUnBind" + test);
return super.onUnbind(intent);
}
}
这可能会有所帮助-谢谢,但不幸的是,解除绑定后服务计时器任务仍然停止。顺便说一句,可能是计时器任务的问题:
code
private TimerTask updateTask=new TimerTask(){@Override public void run(){test++;Log.d(“OREN”,“timer task doing work”+test);};public void runOnTimer(double rad){radius=rad;timer=new timer(“UpdateTimer”);timer.schedule(updateTask,1000L,10*1000L);}code
尝试改用重复的AlarmManager。它将通过挂起的意图向操作系统注册,因此您可以确保它不会停止,除非您明确告诉它。在不知道正在解决的具体问题的情况下,我无法确定这是否是最好的方法。不过,我可以说几句话。1) 您正在从onDestroy()中调用super.onStop()。这无疑最终会产生问题。2) ,您正在UI线程上调用sleep(6000)。您也正在对其进行同步,这是不必要的。如果需要某种延迟,最好在那里使用处理程序。然而,硬编码延迟可能表明您的体系结构需要更改。我建议尽量避免这种情况。:)谢谢,我将等待(6000)更改为while(isMyServiceRunning())。如果我在onStop事件而不是onDestroy事件中停止服务,它不会引起问题吗?我认为将其保留在onDestroy中是可以的。问题是您正在重写onDestroy,但随后调用onStop()。例如,它应该是“public void ondestory(){super.ondestory();}”。您有“public void onDestroy(){super.onStop();}”。而且,听起来您仍然在用“while{(isMyServiceRunning())}”阻塞主UI线程。
public class UpdateService extends Service {
private final IBinder binder = new MyBinder();
public static final String keyVal_arg0="ARG0";
public static final String keyVal_arg1="ARG1";
private Timer timer;
private HTTPHandler http = new HTTPHandler();
private int test=0;
double arg0=0;
String arg1= "";
private TimerTask updateTask = new TimerTask() {
@Override
public void run() {
test++;
Log.d("OREN", "Timer task doing work " + test + " arg0: " + arg0);
//Do some work here
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent!=null){
arg0=intent.getDoubleExtra(keyVal_arg0, 0.002);
arg1=intent.getStringExtra(keyVal_arg1);
timer = new Timer("UpdateTimer");
timer.schedule(updateTask, 1000L, 10 * 1000L);
Log.d("OREN", "ServiceStarted" + test);
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
Log.d("OREN", "OnBind" + test);
return binder;
}
public void setArg0(double d){
arg0=d;
}
// create an inner Binder class
public class MyBinder extends Binder {
public UpdateService getService() {
return UpdateService.this;
}
}
@Override
public void onDestroy() {
Log.d("OREN", "OnDestroy" + test);
super.onDestroy();
}
@Override
public boolean onUnbind(Intent intent) {
Log.d("OREN", "OnUnBind" + test);
return super.onUnbind(intent);
}
}