当前位置: 首页> 娱乐> 明星 > 标识标牌制作设计_ui设计是怎么实现的_软文接单平台_国内比较好的软文网站

标识标牌制作设计_ui设计是怎么实现的_软文接单平台_国内比较好的软文网站

时间:2025/9/30 1:01:05来源:https://blog.csdn.net/github_27263697/article/details/145040064 浏览次数:0次
标识标牌制作设计_ui设计是怎么实现的_软文接单平台_国内比较好的软文网站

目录

一、Service概述

二、生命周期 

三、权限

四、进程生命周期

五、本地Service举例

六、远程Messenger Service举例


一、Service概述

Service 是应用组件,代表一个应用的长时间后台运行的操作,没有交互界面,提供给其他应用一些功能。每个service类必须在清单文件AndroidManifest.xml里做 <service>声明. Services可以被启动通过Context.startService() 和Context.bindService().

services像其他应用对象一样,运行在宿主进程的主线程。这意味着,如果你的服务要执行任何CPU密集型(如MP3播放)或阻塞(如网络)操作,它应该生成自己的线程来完成这项工作。有在Processes and Threads中可以找到更多的信息。 JobIntentService 类作为标准实现类,它有自己的线程可以按部就班的处理事务。

Service 是 应用组件 长时间运行的操作。它不提供界面。一次 一项服务可能会继续运行一段时间,即使用户切换到另一项服务 应用。此外,组件可以绑定到服务以与其进行交互,甚至执行 进程间通信 (IPC)。例如,服务可以处理网络事务、 音乐、执行文件 I/O 或与内容提供程序互动,所有这一切都可以在后台进行。

关于Service类的许多困惑实际上都围绕着它不是什么:

  • Service不是一个独立的进程。Service对象本身并不意味着它在自己的进程中运行;除非另有指定,否则它在其所属的应用程序相同的进程中运行。
  • Service不是一个线程。它本身不是一种在主线程之外执行工作的手段(以避免应用程序无响应错误)。

Service实际上非常简单,提供了2个主要功能:

  • 一个功能是允许应用程序在后台运行处理事情 (甚至不需要有交互界面).当请求系统定时去处理事务时,可以调用 Context.startService()启动Service,一直运行Service,除非用户明确停止Service.
  • 一个功能是应用程序可以提供给其他应用一些功能,当为了与服务交互保持长期的连接时,可以调用Context.bindService(),绑定Service.

当Service组件被创建时,系统会实例化这个组件,并且会在主线程中回调onCreate()等方法。Service是否可以用适当的操作实现这些操作,例如创建一个可以工作的辅助线程。

因为Service如此简单,所以你可以通过想用的简单的或者复杂的方式与它交互。把Service当作Java本地对象,创造直接的回调方法(详细说明请看本地Service示例)通过AIDL提供全部远程接口。

二、生命周期 

系统启动Service有两种方式。通过调用Context.startService() 启动Service,然后系统检索到service后,创建它,并调用onCreate,然后通过客户端提供的参数回调onStartCommand(Intent, int, int)方法。 service会一直运行,直到调用Context.stopService() 或stopSelf() 停止Service. 请注意,对Context.startService()的多次调用不会嵌套 (多次调用start会回调多次onStartCommand()方法), 所以无论启动多少次service,只要调用一次Context.stopService() 或者stopSelf(),Service就会被停止。无论怎样,services可以用 stopSelf(int) 方法确保只有在intents开始处理后,才能停止service。

对于已经启动的services, 它们还可以选择以另外两种主要的运行模式运行,依赖于onStartCommand()的返回值: START_STICKY,表示services当被需要时,会被明确的启动或者停止。当使用START_NOT_STICKY or START_REDELIVER_INTENT 于服务时,服务当处理任何指令发送它们时,服务应该一直保持运行。详情请参考有关文档。

客户端也可以用Context.bindService()获取与service的持续连接。同样创建没有运行的服务,但是不回调onStartCommand()方法. 客户端可以收到从服务  onBind(Intent)方法返回的IBinder 对象,允许客户端制造回调给service。service运行时长和连接建立时长一样。通常 IBinder被返回给在aidl中创建的复杂接口。

service可以被启动或者绑定。 can be both started and have connections bound to it. 在这种情况下,系统可以保持service运行只要它被启动或者被绑定通过 Context.BIND_AUTO_CREATE 标识. 一旦这两种情况都不成立后,service的onDestroy() 方法会被调用或者有效的中断。所有的清理工作也应该在onDestroy()方法返回之前.

三、权限

当一个服务在其清单文件(manifest)的<service>标签中被声明时,可以强制实现对该服务的全局访问。通过上述操作,其他应用也需要声明对应的权限<uses-permission> 在自己的清单文件里,用以启动,停止,或绑定service.

Build.VERSION_CODES.GINGERBREAD(即Android 2.3姜饼版本)开始,当使用Context.startService(Intent)方法启动服务时,您还可以在Intent上设置Intent.FLAG_GRANT_READ_URI_PERMISSION和/或Intent.FLAG_GRANT_WRITE_URI_PERMISSION标志。这将授予服务对Intent中特定URI的临时访问权限。该访问权限将一直保留,直到服务为该启动命令或后续命令调用了stopSelf(int)方法,或者服务已经完全停止为止。

这适用于向那些没有请求保护服务的权限的其他应用授予访问权限,甚至当服务根本没有被导出时也同样有效。

另外,service可以用权限保护IPC调用,在执行调用实现之前需要调用ContextWrapper.checkCallingPermission(String) 方法。

查看Security and Permissions 文档,大体上详细讲述了权限和安全的内容。

四、进程生命周期

只要服务已被启动或有客户端绑定到该服务,Android系统就会尝试保持承载该服务的进程存活。当内存低时,需要杀死进程,保留service的进程根据下面可能性有更高的优先级:

  • 当前service执行代码在onCreate()onStartCommand(), 或onDestroy() 方法里, 所在进程将会成为前台进程,以确保代码执行期间进程不被杀死。

  • 服务已经被启动,所在进程被认为比其他可见进程优先级低,比其他任何不可见进程优先级高。因为一般只有一些对用户可见的进程除非在低内存下才会被杀死。然而,由于用户无法直接感知到后台服务的存在,在这种状态下,该服务被视为可被终止的有效候选对象,因此您应该为此做好准备。特别的是,对于长时间在后台运行的services会增加被killl掉的风险,且如果启动足够长的时间,确保被kill掉。

  • 如果客户端绑定service, 宿主进程比任何进程优先级都要高。如果客户端对用户是可见的,那么service本身对用户也是可见的。客户端影响了service重要性的通过设置如下标识实现的: Context.BIND_ABOVE_CLIENTContext.BIND_ALLOW_OOM_MANAGEMENTContext.BIND_WAIVE_PRIORITYContext.BIND_IMPORTANT, and Context.BIND_ADJUST_WITH_ACTIVITY.

  • 当被开启的service调用startForeground(int, android.app.Notification) 将service切换到前台,系统会认为用户知道service运行着处理事务,所以即使在低内存时,用户也不会kill掉service。 (理论上,在当前前台应用程序面临极端内存压力的情况下,该服务仍有可能被终止,但在实际操作中,这通常不必担心。)

大多数时候,运行着的service,在内存高度紧缺的情况下,依旧可能被kill掉。如果被kill掉,系统会在稍后重启service。这带来的一个重要后果是,如果您在onStartCommand()方法中安排异步执行工作或在其他线程中执行工作,那么您可能希望使用START_FLAG_REDELIVERY标志,以便系统在您的服务在处理Intent时被终止的情况下重新传递该Intent,从而确保它不会丢失。

当然,与服务运行在同一进程中的其他应用程序组件(如Activity)可以提高整个进程的重要性,而不仅仅是服务本身的重要性。

五、本地Service举例

Service最常见的一种用途是作为应用程序其他部分的辅助组件,在与应用程序其他组件相同的进程中运行。除非明确指定,否则.apk文件中的所有组件都在同一个进程中运行,因此这是一种典型情况。

当以这种方式使用,即假设组件在同一个进程中时,可以极大地简化它们之间的交互:服务的客户端可以简单地将从服务接收到的IBinder转换为服务发布的具体类。

这里展示了一个Service的这种用法的示例。首先是Service本身,它在绑定时发布了一个自定义类:

public class LocalService extends Service {private NotificationManager mNM;//Notification的标识id,可以用它启动Notification或者取消它。private int NOTIFICATION = R.string.local_service_started;/*** 客户端访问的类。因为service和客户端在同一个进程,所以不需要处理IPC.*/public class LocalBinder extends Binder {LocalService getService() {return LocalService.this;}}@Overridepublic void onCreate() {mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);// 显示通知.showNotification();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.i("LocalService", "Received start id " + startId + ": " + intent);return START_NOT_STICKY;}@Overridepublic void onDestroy() {// 取消通知mNM.cancel(NOTIFICATION);// Tell the user we stopped.Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();}@Overridepublic IBinder onBind(Intent intent) {return mBinder;}// 客户端收到的交互对象。远程service是更好的例子。private final IBinder mBinder = new LocalBinder();/*** 当service启动时显示通知*/private void showNotification() {// In this sample, we'll use the same text for the ticker and the expanded notificationCharSequence text = getText(R.string.local_service_started);// The PendingIntent to launch our activity if the user selects this notificationPendingIntent contentIntent = PendingIntent.getActivity(this, 0,new Intent(this, LocalServiceActivities.Controller.class), 0);// Set the info for the views that show in the notification panel.Notification notification = new Notification.Builder(this).setSmallIcon(R.drawable.stat_sample)  // the status icon.setTicker(text)  // the status text.setWhen(System.currentTimeMillis())  // the time stamp.setContentTitle(getText(R.string.local_service_label))  // the label of the entry.setContentText(text)  // the contents of the entry.setContentIntent(contentIntent)  // The intent to send when the entry is clicked.build();// Send the notification.mNM.notify(NOTIFICATION, notification);}
}

这样,客户端可以直接访问运行中的service,例如:

/*** 绑定和解绑本地service举例。* 绑定service后,可以收到与service交互的对象。** 请注意,这里将其作为内部类实现只是为了保持示例的完整性;通常,这段代码会出现在某个单独的类中。*/
public static class Binding extends Activity {// 除非客户端收到service的状态,否则不要解绑service。private boolean mShouldUnbind;// 为了绑定service,首先确定此值不能为null.private LocalService mBoundService;private ServiceConnection mConnection = new ServiceConnection() {public void onServiceConnected(ComponentName className, IBinder service) {// 当与service的连接建立以后,通过service对象可以与service交互。因为绑定了清晰的service,所以可以强制转化IBinder对象,并且直接访问此对象。mBoundService = ((LocalService.LocalBinder)service).getService();// Tell the user about this for our demo.Toast.makeText(Binding.this, R.string.local_service_connected,Toast.LENGTH_SHORT).show();}public void onServiceDisconnected(ComponentName className) {//当与服务器的连接意外断开时,即其进程崩溃时,会调用此方法。由于它运行在我们的同一进程中,我们理论上不应该看到这种情况发生。mBoundService = null;Toast.makeText(Binding.this, R.string.local_service_disconnected,Toast.LENGTH_SHORT).show();}};void doBindService() {// 创建与service连接。使用清晰的类名,建立与具体service的连接。if (bindService(new Intent(Binding.this, LocalService.class),mConnection, Context.BIND_AUTO_CREATE)) {mShouldUnbind = true;} else {Log.e("MY_APP_TAG", "Error: The requested service doesn't " +"exist, or this client isn't allowed access to it.");}}void doUnbindService() {if (mShouldUnbind) {// Release information about the service's state.unbindService(mConnection);mShouldUnbind = false;}}@Overrideprotected void onDestroy() {super.onDestroy();doUnbindService();}

六、远程Messenger Service举例

​​​​​ 

关键字:标识标牌制作设计_ui设计是怎么实现的_软文接单平台_国内比较好的软文网站

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: