这篇文章主要围绕java-Android服务(“startService和stopService”)和“播放/停止”按钮合而为一和java服务启动展开,旨在为您提供一份详细的参考资料。我们将全面介绍j
这篇文章主要围绕java-Android服务(“ startService和stopService”)和“播放/停止”按钮合而为一和java服务启动展开,旨在为您提供一份详细的参考资料。我们将全面介绍java-Android服务(“ startService和stopService”)和“播放/停止”按钮合而为一的优缺点,解答java服务启动的相关问题,同时也会为您带来Andorid之提示java.lang.RuntimeException: Unable to start service net.gotev.uploadservice.UploadService@、Android service (一) startService vs bindService、android service 之startService(...)、Android Service 启动、绑定后还需要 StopService 吗?的实用方法。
本文目录一览:- java-Android服务(“ startService和stopService”)和“播放/停止”按钮合而为一(java服务启动)
- Andorid之提示java.lang.RuntimeException: Unable to start service net.gotev.uploadservice.UploadService@
- Android service (一) startService vs bindService
- android service 之startService(...)
- Android Service 启动、绑定后还需要 StopService 吗?
java-Android服务(“ startService和stopService”)和“播放/停止”按钮合而为一(java服务启动)
我正在开发一个Android应用程序,需要创建一个按钮,该按钮将成为用于播放和停止Android服务的“播放/停止”按钮.
>播放按钮用于startActivity();
>停止按钮用于stopActivity();
我该怎么做?
解决方法:
您只需要声明一个标志变量,并根据这样的标志值声明onclick()的主体.
public class ServiceActivity extends Activity {
Button play;
int button_status=1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
play=(Button)findViewById(R.id.button1);
play.setonClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// Todo Auto-generated method stub
if(button_status == 1)//play the service
{
button_status=0;
Intent i=new Intent(ServiceActivity.this,Playing.class);
startService(i);
}
else//stop the service
{
button_status=1;
Intent i=new Intent(ServiceActivity.this,Playing.class);
stopService(i);
}
});
}
}
或者您可以使用ToggleButton作为您的腰包.
Andorid之提示java.lang.RuntimeException: Unable to start service net.gotev.uploadservice.UploadService@
1 问题
用android-upload-service上传一个文件提示错误如下
04-15 17:46:33.245 24932 24932 E AndroidRuntime: Process: com.appsinnova.android.keepshare, PID: 24932
04-15 17:46:33.245 24932 24932 E AndroidRuntime: java.lang.RuntimeException: Unable to start service net.gotev.uploadservice.UploadService@ce7b171 with Intent { act=net.gotev.uploadservice.action.upload cmp=packageName/net.gotev.uploadservice.UploadService (has extras) }: java.lang.IllegalArgumentException: Hey dude, please set the namespace for your app by following the setup instructions: https://github.com/gotev/android-upload-service/wiki/Setup
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4013)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at android.app.ActivityThread.access$1800(ActivityThread.java:229)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1908)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at android.os.Looper.loop(Looper.java:226)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7223)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:576)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:961)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: Caused by: java.lang.IllegalArgumentException: Hey dude, please set the namespace for your app by following the setup instructions: https://github.com/gotev/android-upload-service/wiki/Setup
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at net.gotev.uploadservice.UploadService.onStartCommand(UploadService.java:257)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3980)
04-15 17:46:33.245 24932 24932 E AndroidRuntime: ... 8 more
04-15 17:46:33.247 606 635 I vendor.mediatek.hardware.power@2.1-impl: notifyAppState_2_1 pack:com.appsinnova.android.keepshare, act:com.appsinnova.android.keepshare, pid:24932, uid:10293, state:3
04-15 17:46:33.263 24932 24932 I Process : Sending signal. PID: 24932 SIG: 9
04-15 17:46:33.350 1254 3575 D Dex2oatManagerService: Display listener for pid 24932 died.
2 原因
UploadService没有注册
3 解决办法
在继承的Application类里面的onCreate函数里面添加如下代码
override fun onCreate() {
super.onCreate()
UploadService.NAMESPACE = packageName;
}
- 点赞
- 收藏
- 分享
-
- 文章举报

Android service (一) startService vs bindService
service 简介
- service 是Android的4大组件之一, 用于在后台<em>(这里指的是service不提供UI, 用户不可见)</em>执行任务.
- service 是在UI线程上被创建, 并且在UI线程上运行的, 如果service需要执行耗时操作,那么需要自己开启线程或线程池,然后在子线程中执行.
- service 有2种启动方式: startService & bindService <em>(也可以同时使用这2种方式)</em>
使用service VS 在其他组件中开启子线程
首先要说明的是service和thread是2个并不对等的概念, 这里之所以将它们放在一起比较, 是因为不少人在实际开发中会遇到这样的抉择: 是创建一个service去执行一个操作呢, 还是直接开启一个子线程?
service 和 thread 的区别
- service
- service是Android提供的一个基础组件, 当进程中有存活的service时, 那么这个进程至少拥有
Service process
级别的优先级<em>(Android定义了5个级别的进程优先级)</em>. 因此这个进程退到后台后, 也不容易被回收. - 当系统负载过高杀死该进程之后, 该service依然会在系统资源变得充足之后再次运行<em>(如果
onStartCommand
方法返回START_STICKY
或者START_REDELIVER_INTENT
的话)</em>. 这就意味着即使包含service的进程可能会被系统杀死, 但相应的任务依然是有机会恢复执行的, - service具有高可复用性, 可以为不同的进程, 不同的应用提供服务
- service是Android提供的一个基础组件, 当进程中有存活的service时, 那么这个进程至少拥有
- thread
- thread并不是Android提供的概念, 只是一个单独的执行单元, 可以用于实现负载均衡. 在Android中使用thread的一个常见情形是避免ANR.
何时使用service, 何时使用thread
- 如果该任务的结果只在用户与其交互时有效<em>(例如界面显示时有效, 界面隐藏或销毁之后就无效了)</em>, 那么适合用thread去执行.<em>(例如在界面上显示一张远程图片, 就可以在子线程中去下载图片)</em>
- 如果该任务在用户退到后台后仍然希望执行, 或者改任务并不直接影响到用户的交互, 那么适合使用service(通常在service中也要创建thread去执行).<em>(例如下载服务)</em>
startService VS bindService
startService 和 bindService 的简介
- startService
- 通过startService启动的service将在后台持续运行,直到某个组件调用stopService,或者该service自己调用stopSelf,或者因为内存不足而被系统销毁. <em>这意味着调用方通常需要管理service的生命周期</em>
- 通过这种方式启动的Service和启动它的组件之间没有绑定关系(可以理解为游离的),因此启动它的组件被销毁了,并不会影响到service的运行
onStartCommand
的返回值对service的生命周期的影响.(仅当service没有正常终止而是被系统销毁,此方法的返回值才会有效)START_STICKY
: 系统会重新创建该service,并调用onStartCommand
方法,传入的intent
为null
.<em>(适用于需要长期存在的一些任务)</em>START_NOT_STICKY
: 系统不会再创建该service, 除非其他组件start它. <em>(通常建议使用它)</em>START_REDELIVER_INTENT
: 系统会重新创建该service,并调用onStartCommand
方法,传入的intent
为service销毁之前的最后一个intent. <em>(下载服务适用于此方式)</em>
<font color=red>注意: </font> 在Android 2.0以后, onStartCommand()方法默认返回START_STICKY
, 通常情况下, 我们需要考虑我们的服务是否应该使用START_STICKY
, 如果不是,则需要重写此方法.
-
bindService
- bind 这种方式使得
发起绑定的组件
和被绑定的service
形成了一个client-server
模式.当发起绑定的组件
被销毁后,被绑定的service
也会随之销毁.<em>(前提是没有其他的组件和它绑定, 并且该service没有被start, 或者虽然被start过, 但已经执行了stopService/stopSelf 方法)</em> - 当绑定service的组件C被销毁后,service也会被销毁(service的onDestroy会被调用),不管组件C在销毁前是否调用了unbindService.<em>(如果没有调用unbindService,那么Logcat中会打印出
android.app.ServiceConnectionLeaked
异常, 不过通过MAT分析内存dump文件,可以看出 绑定service的组件以及service自身都是可以被回收的)</em> - 通过bindService的方式, client可以得到一个IBinder的接口, 进而可以将其转换为IInterface接口, 用于和远程service进行通信.<em>(如果client和server在同一个进程内, 那么service返回的IBinder直接提供一个返回Service引用的方法, 使用起来可能会更方便一些)</em>
- 当被绑定的service被销毁之后,
ServiceConnection.onServiceDisconnected
会被调用,当系统重新创建该service之后,ServiceConnection.onServiceConnected
会再次被触发 - <font color=red>注意:</font>要支持bind, service的onBind方法必需返回一个IBinder对象, 如果返回null, 那么要绑定该service的组件提供的
ServiceConnection.onServiceConnected
将不会被调用,也就是说绑定会失败.<em>(注意:该service仍然会被创建,也会一直运行,直到要绑定它的那个组件销毁的时候一起销毁)</em>. 如果希望某个service不允许被任何其他组件绑定, 那么在其onBind方法中返回null就好了. - <font color=red>重要:</font>通过相同的Intent调用bindService方法, service的onBind方法只会被调用一次(即第一次会被调用), 对于后续的bindService调用, 系统将会直接返回上一此的IBinder.
// 这里比较 Intent 是否相同, 使用的是: android.content.Intent.FilterComparison.equals() 方法 // 每次 onBind 方法成功执行之后, 对应的 IntentBindRecord 会保存到 ServiceRecord 之中 // com.android.server.am.ServiceRecord final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings = new ArrayMap<Intent.FilterComparison, IntentBindRecord>(); // 对于bindService(Intent service, ServiceConnection conn, int flags) // 如果参数 Intent 之前使用过, 那么对应的service的onBind方法不会再调用, 而是直接返回之前的IBinder
- 只有当所有绑定到该service的组件都与其解绑了,
onUnbind
方法才会被调用.(如果onUnbind返回true,那么下次绑定service,系统创建后将不会调用onBind,而是调用onRebind,并返回之前的IBinder)
- bind 这种方式使得
何时使用startService, 何时使用bindService
- 如果只是要启动service去执行一个任务, 则使用startService比较合适.
- 如果启动service之后要与它进行交互<em>(例如调用服务的方法, 甚至是client与server的双向通行)</em>, 则使用bindService比较合适.
既start又bind
通常这样做的目的是:
- 需要service能长时间的运行, 而不要关心启动它的组件是否被销毁. <em>start</em>
- 需要和service进行交互 以调用service的一些方法. <em>bind</em>
例如:实现一个DownloadService
1. startService目的: 使得 DownloadService 可以长久的在后台运行
2. bindService目的: 使用 DownloadService 提供的下载进度等Api
// 顺便说一句, 像DownloadService这样的服务, onStartCommand()方法建议返回START_REDELIVER_INTENT
此时要终止该service,需要同时具备下面2个条件:
- service调用了
stopSelf
或者某个组件调用了stopService
- 所有绑定到该service的组件都已解绑或者被销毁
隐式Intent的风险
之所以说通过隐式Intent启动service存在安全风险,是因为:
- 通常调用者无法确定通过隐式Intent启动的service是哪一个(这个service甚至可能来自其他应用)
- service在后台运行,没有用户界面.因此很难感知到这个service的存在以及它在干什么
通常建议startService
和bindService
使用显示Intent.并且在Manifest文件中定义service时,不应该提供<intent-filter>
, export
设置为false
(如果没有提供<intent-filter>
,那么export默认就是false)
**注意:**如果targetSdkVersion
>=21的话,startService
,bindService
不能使用隐式Intent
,否则会抛出IllegalArgumentException
ContextImpl.java
private void validateServiceIntent(Intent service) {
if (service.getComponent() == null && service.getPackage() == null) {
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
IllegalArgumentException ex = new IllegalArgumentException("Service Intent must be explicit: " + service);
throw ex;
} else {
Log.w(TAG, "Implicit intents with startService are not safe: " + service
+ " " + Debug.getCallers(2, 3));
}
}
}
tips
- 使用隐式Intent, 但是限定被启动的组件在指定app中的方法:
//在使用隐式Intent的时候, 可以通过 Intent.setPackage(packagename);
//来将组件的匹配限制在某个应用内.
//限制该隐式intent只匹配自己应用内的某个组件
intent.setPackage("my package name");
BroadcastReceiver.onReceive(Context context, Intent intent)
方法中的context
是不能用来绑定service的, 因为该context是:android.app.ReceiverRestrictedContext
重写了bindService方法, 并抛出异常.
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
throw new ReceiverCallNotAllowedException("BroadcastReceiver components are not allowed to bind to services");
}
android service 之startService(...)
1,创建一个MusicPlayService继承Service,并重写onCreat()方法和onStartCommand(...)方法
public class MusicPlayService extends Service{
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.e(TAG, "MusicSerice onCreate()");
//musicplay=BackgroundMusicPlay.getBackgroundMusicPlay(this);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "MusicSerice---> onStartCommand()");
playMusic();
return super.onStartCommand(intent, flags, startId);
}
public void playMusic()
{
musicplay.musicPlay();
// mp=MediaPlayer.create(getApplicationContext(), R.raw.newgalactic);
// mp.setLooping(true);
// mp.start();
}
}
注意:由于onStart(...)方法在level 2.0之后已经失效,所以2.0之后用onStartCommand代替,具体请查看API文档http://tool.oschina.net/apidocs/apidoc?api=android/reference
2,在activity中通过startService(...)调用服务
Intent intent2=new Intent(ShorMusicPlay.this, MusicPlayService.class);
startService(intent2); //启动服务
stopService(intent2);//结束服务
Android Service 启动、绑定后还需要 StopService 吗?
假设:
Activity A 启动 (StartService) 一个 Service 后,Activity A 销毁了并切换到 Activity B (但没有调用 StopService,所以 Service 还在运行)。
然后 Activity B 绑定 (BindService) 这个 Service, 当 Activity B 销毁了,是否 Service 也跟着销毁?还是要再次调用 StopService?
(Activity A) StartService->(Activity B) BindService->(Activity B 销毁) 是否还需要调用 StopService??
关于java-Android服务(“ startService和stopService”)和“播放/停止”按钮合而为一和java服务启动的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Andorid之提示java.lang.RuntimeException: Unable to start service net.gotev.uploadservice.UploadService@、Android service (一) startService vs bindService、android service 之startService(...)、Android Service 启动、绑定后还需要 StopService 吗?的相关信息,请在本站寻找。
本文标签: