Android中的Service

news/2025/1/10 10:30:12/

一、Service的简介

Service是Android系统四大组件之一,定义是服务,一种长时间在后台长时间运行的操作或处理异步任务的组件。Service可以不依赖于用户界面的情况下运行,并且可以在应用被关闭后继续运行。

二、<service> 标签详解

在 Android 应用开发中,<service> 标签用于在 AndroidManifest.xml 文件中声明一个服务。服务是一种后台组件,可以在不与用户界面交互的情况下执行长时间运行的操作。为了正确配置和管理服务,<service> 标签提供了多个属性,下面是对这些属性的详细说明:

androidname_8">1. android:name

  • 含义:指定服务类的名称。
  • 必填项:是。
  • 示例
    • 相对路径:android:name=".MyService"
    • 完整路径:android:name="com.example.myapp.MyService"
    • 使用 . 开头表示在应用的包名下。

androidenabled_16">2. android:enabled

  • 含义:指定服务是否在应用启动后可以被系统调用。
  • 默认值true(启用)。
  • 示例
    • 启用服务:android:enabled="true"
    • 禁用服务:android:enabled="false"
    • 如果设置为 false,则服务需要通过代码手动启用。

androidexported_24">3. android:exported

  • 含义:指定服务是否可以被其他应用的组件启动。
  • 默认值false(不导出)。
  • 注意事项
    • 如果服务包含 <intent-filter>,系统会默认将其设置为 true
    • 如果不希望服务被其他应用访问,务必设置为 false
  • 示例
    • 允许外部应用访问:android:exported="true"
    • 仅限本应用访问:android:exported="false"

androidpermission_34">4. android:permission

  • 含义:指定启动或绑定服务所需的权限。
  • 示例
    • 设置权限:android:permission="com.example.myapp.permission.MY_SERVICE_PERMISSION"
    • 其他应用需要声明并获取该权限才能启动或绑定此服务。

androidprocess_40">5. android:process

  • 含义:指定服务运行的进程名称。
  • 默认值:服务与应用运行在同一个进程中。
  • 注意事项
    • 可以为服务分配独立的进程,以实现进程隔离。
    • 进程名以 : 开头表示进程是应用的私有进程。
  • 示例
    • 独立进程:android:process=":my_process"
    • 共享进程:android:process="com.example.myapp.shared_process"

androidisolatedProcess_50">6. android:isolatedProcess

  • 含义:指定服务是否运行在一个隔离的进程中。
  • 默认值false
  • 注意事项
    • 隔离进程没有应用的上下文,安全性更高,但资源受限。
    • 通常用于需要更高安全级别的场景。
  • 示例
    • 启用隔离进程:android:isolatedProcess="true"

androidallowTaskReparenting_59">7. android:allowTaskReparenting

  • 含义:指定服务是否可以在任务重新分配时重新关联。
  • 默认值false
  • 示例
    • 允许重新关联:android:allowTaskReparenting="true"

androidlabel_65">8. android:label

  • 含义:指定服务的显示名称。
  • 示例
    • 引用字符串资源:android:label="@string/service_name"

androiddescription_70">9. android:description

  • 含义:指定服务的详细描述。
  • 示例
    • 引用字符串资源:android:description="@string/service_description"

androidicon_75">10. android:icon

  • 含义:指定服务的图标。
  • 示例
    • 引用图标资源:android:icon="@mipmap/ic_service"

androiddirectBootAware_80">11. android:directBootAware

  • 含义:指定服务是否在设备直接启动模式下运行。
  • 默认值false
  • 示例
    • 允许直接启动模式:android:directBootAware="true"

androidstopWithTask_86">12. android:stopWithTask

  • 含义:指定服务是否在任务被清除时停止。
  • 默认值true
  • 示例
    • 与任务一起停止:android:stopWithTask="true"
    • 继续运行:android:stopWithTask="false"

androidtestOnly_93">13. android:testOnly

  • 含义:指定服务是否仅用于测试。
  • 默认值false
  • 示例
    • 仅测试使用:android:testOnly="true"

示例代码

以下是一个完整的 <service> 标签示例:

<serviceandroid:name=".MyService"android:enabled="true"android:exported="false"android:permission="com.example.myapp.permission.MY_SERVICE_PERMISSION"android:process=":my_process"android:label="@string/service_name"android:description="@string/service_description"android:icon="@mipmap/ic_service"android:directBootAware="true"android:stopWithTask="false" />

属性总结

属性含义默认值示例
android:name服务的类名必填.MyService
android:enabled服务是否可以被启动truetrue
android:exported服务是否可以被外部应用启动falsetrue
android:permission启动或绑定服务所需的权限-com.example.permission
android:process服务运行的进程名称-:my_process
android:isolated服务是否运行在隔离进程中falsetrue
android:label服务的显示名称-@string/service_name
android:icon服务的图标-@mipmap/ic_service
android:stopWithTask服务是否随任务清除而停止truefalse
android:directBoot服务是否支持直接启动模式falsetrue

好的,我明白了。以下是调整后的内容,包括了在 AndroidManifest.xml 中的配置说明:

三、Service 的启动方式

在 Android 开发中,服务可以通过不同方式启动,每种方式都有其特定的应用场景和行为。以下是三种主要的启动方式:

1. 启动服务(Start Service)

  • 概念:启动服务是通过调用 startService(Intent) 方法来启动的。启动后,服务会在后台独立运行,直到主动调用 stopSelf() 或被外部调用 stopService() 停止。
  • 特点
    • 启动后与启动它的组件无关,即使启动它的组件被销毁,服务也会继续运行。
    • 适合执行不需要与启动组件通信的后台任务。
  • 生命周期
    • onCreate():服务首次创建时调用。
    • onStartCommand(Intent, int, int):每次调用 startService() 时都会触发。
    • onDestroy():服务停止时调用。
  • 示例代码
    // 启动服务的 Activity
    public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 启动服务Intent intent = new Intent(this, MyService.class);startService(intent);}
    }// 服务实现
    public class MyService extends Service {@Overridepublic void onCreate() {super.onCreate();// 服务首次创建时执行}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// 处理任务return START_STICKY; // 服务被杀后重启}@Overridepublic void onDestroy() {super.onDestroy();// 服务停止时执行}@Overridepublic IBinder onBind(Intent intent) {return null; // 不支持绑定模式}
    }
    
  • 清单文件配置
    • 为了确保服务可以被启动,需要在 AndroidManifest.xml 中声明服务。
    <service android:name=".MyService" />
    

2. 绑定服务(Bind Service)

  • 概念:绑定服务是通过调用 bindService(Intent, ServiceConnection, int) 方法来启动的。绑定服务允许组件与服务进行直接通信,通常通过实现 ServiceConnection 接口来实现。
  • 特点
    • 服务与绑定它的组件之间存在强关联。如果最后一个绑定组件解绑,服务会自动停止。
    • 适合需要与服务交互的场景,例如传递数据或调用服务的方法。
  • 生命周期
    • onCreate():服务首次创建时调用。
    • onBind(Intent):绑定服务时调用,返回一个 IBinder 对象以允许客户端与服务通信。
    • onUnbind(Intent):所有客户端解绑时调用。
    • onDestroy():服务停止时调用。
  • 示例代码
    // 绑定服务的 Activity
    public class MainActivity extends AppCompatActivity {private MyService.MyBinder binder;private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {binder = (MyService.MyBinder) service;// 获取服务实例并调用服务方法binder.getService().doSomething();}@Overridepublic void onServiceDisconnected(ComponentName name) {binder = null;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 绑定服务Intent intent = new Intent(this, MyService.class);bindService(intent, connection, BIND_AUTO_CREATE);}@Overrideprotected void onDestroy() {super.onDestroy();// 解绑服务unbindService(connection);}
    }// 服务实现
    public class MyService extends Service {private final MyBinder binder = new MyBinder();public class MyBinder extends Binder {public MyService getService() {return MyService.this;}}public void doSomething() {// 服务方法}@Overridepublic IBinder onBind(Intent intent) {return binder;}
    }
    
  • 清单文件配置
    • 为了确保服务可以被绑定,需要在 AndroidManifest.xml 中声明服务。
    <service android:name=".MyService" />
    

3. 混合启动(Start + Bind)

  • 概念:服务可以同时支持启动和绑定模式。通过这种方式,服务既可以独立运行,也可以与组件交互。
  • 特点
    • 允许服务通过 startService() 启动,同时支持通过 bindService() 与组件通信。
    • 如果服务是通过 startService() 启动的,调用 unbindService() 不会停止服务,除非显式调用 stopService()stopSelf()
  • 示例代码
    // 启动并绑定服务的 Activity
    public class MainActivity extends AppCompatActivity {private MyService.MyBinder binder;private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {binder = (MyService.MyBinder) service;// 获取服务实例并调用服务方法binder.getService().doSomething();}@Overridepublic void onServiceDisconnected(ComponentName name) {binder = null;}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 启动服务Intent intent = new Intent(this, MyService.class);startService(intent);// 绑定服务bindService(intent, connection, BIND_AUTO_CREATE);}@Overrideprotected void onDestroy() {super.onDestroy();// 解绑服务unbindService(connection);}
    }// 服务实现
    public class MyService extends Service {private final MyBinder binder = new MyBinder();public class MyBinder extends Binder {public MyService getService() {return MyService.this;}}public void doSomething() {// 服务方法}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return START_STICKY;}@Overridepublic IBinder onBind(Intent intent) {return binder;}
    }
    
  • 清单文件配置
    • 为了确保服务可以同时支持启动和绑定,需要在 AndroidManifest.xml 中声明服务。
    <service android:name=".MyService" />
    

特殊配置

在某些情况下,可能需要在 AndroidManifest.xml 中添加额外的配置来支持特定的启动方式或行为:

  1. 前台服务

    • 如果需要将服务作为前台服务运行,以避免被系统杀死,可以在 onStartCommand() 中调用 startForeground(int, Notification) 方法,并在 AndroidManifest.xml 中声明服务类型为 foreground
    <service android:name=".MyService" android:foregroundServiceType="dataSync" />
    
  2. 启动类型

    • 可以在 AndroidManifest.xml 中设置服务的启动类型,例如 isolatedProcesssingleTop
    <service android:name=".MyService" android:process=":isolated" />
    
  3. 权限

    • 如果服务需要特定的权限,可以在 AndroidManifest.xml 中声明。
    <service android:name=".MyService" android:permission="android.permission.BIND_OVERLAY_SERVICE" />
    
  4. Intent 过滤器

    • 如果服务需要通过特定的 Intent 过滤器来响应某些类型的启动请求,可以在 AndroidManifest.xml 中定义。
    <service android:name=".MyService"><intent-filter><action android:name="com.example.ACTION_START_MY_SERVICE" /></intent-filter>
    </service>
    

启动方式总结

启动方式特点适用场景清单文件配置
Start Service服务独立运行,与启动组件无关后台任务(如音乐播放、下载)<service android:name=".MyService" />
Bind Service服务与组件绑定,组件销毁时服务可能停止需要与服务交互的场景(如RPC调用)<service android:name=".MyService" />
混合启动支持独立运行与绑定通信,灵活性高需要兼具独立运行与交互的场景<service android:name=".MyService" />

明白了,您希望保留引用部分,并在引用之后单独讨论关于Service的生命周期的内容。以下是您原文中的引用部分以及对Service生命周期的进一步讨论:


四、Service的生命周期

和Activity一样,Service也有自己的生命周期,但相较于Activity的生命周期,Service的生命周期更加简单。以下是Android开发手册中的相关描述:

服务的生命周期比 activity 的生命周期简单得多。但更重要的是 请务必密切关注服务的创建和销毁方式,因为
服务可以在用户不知情的情况下在后台运行。

服务生命周期(从创建到销毁)可以遵循 以下两个路径之一:

  • 启动服务
    该服务在其他组件调用 startService() 时创建。然后无限期运行 通过调用 stopSelf()
    自行停止运行。另一个组件也可以停止 调用 stopService() 的服务。服务停止后,系统会将其销毁。

  • 绑定服务
    该服务在其他组件(客户端)调用 bindService() 时创建。然后,客户端与服务进行通信 通过 IBinder接口实现。客户端可以通过调用 unbindService()。多个客户端可以绑定到同一个服务,当所有这些服务都解除绑定后,系统就会销毁该服务。服务 无需自行停止。

这两条路径并非完全独立。你可以绑定到一个 开头是 startService()。例如,您可以 使用 Intent(用于标识要播放的音乐)调用startService(),从而启动后台音乐服务。稍后, 例如,当用户想要对播放器进行一定程度的控制或获取有关 当前歌曲,activity可以通过调用 bindService() 绑定到该服务。在这种情况下,除非所有客户端都取消绑定,否则 stopService()stopSelf() 不会实际停止服务。


对Service生命周期的进一步讨论

在理解Service的生命周期时,除了上述Android开发手册中的描述外,还有一些重要的细节和实际开发中需要注意的点:

1. Service的生命周期回调方法

与Activity类似,Service的生命周期也由一系列回调方法组成。主要的回调方法包括:

  • onCreate():当服务第一次被创建时调用,用于初始化服务的状态。该方法只会被调用一次,即使服务被多次启动或绑定。

  • onStartCommand():当其他组件调用startService()时,系统会调用此方法。开发者可以在此方法中执行需要在后台运行的任务。需要注意的是,onStartCommand()可能会被多次调用,因此需要确保任务的线程安全性。

  • onBind():当其他组件调用bindService()时,系统会调用此方法。该方法必须返回一个IBinder对象,用于客户端与服务进行通信。如果服务不允许绑定,可以返回null

  • onDestroy():当服务不再使用且被销毁时,系统会调用此方法。开发者可以在此方法中释放资源,例如关闭数据库连接、停止后台线程等。

2. 启动服务与绑定服务的生命周期差异
  • 启动服务(Started Service

    • 启动服务在startService()调用后创建,并且除非显式调用stopService()stopSelf(),否则服务将一直运行。
    • 启动服务的生命周期独立于启动它的组件(如Activity)。即使启动它的组件被销毁,服务仍然可以继续运行。
    • 启动服务的典型应用场景包括后台任务(如下载文件、播放音乐等)。
  • 绑定服务(Bound Service

    • 绑定服务在bindService()调用后创建,并且只要有一个客户端绑定到该服务,服务就会保持运行。
    • 绑定服务的生命周期依赖于绑定的客户端。当所有客户端都调用unbindService()解除绑定时,服务会被销毁。
    • 绑定服务的典型应用场景包括客户端与服务之间的实时通信(如获取数据更新、控制设备状态等)。
3. 启动与绑定的组合使用

在实际开发中,一个服务可能同时支持启动和绑定。例如,一个音乐播放服务可能最初是通过startService()启动的,以便在后台播放音乐。随后,用户可能希望控制播放器(如暂停、切换歌曲),这时可以通过bindService()将Activity绑定到服务上。在这种情况下,即使所有客户端都解除了绑定,服务仍然可以通过startService()保持运行,直到显式调用stopService()stopSelf()

4. 前台服务的生命周期

除了普通的启动服务和绑定服务,Android还支持前台服务(Foreground Service)。前台服务需要显示通知,并且具有更高的优先级,以确保它们在系统资源紧张时不会被轻易杀死。前台服务的生命周期与启动服务类似,但需要调用startForeground()方法将其提升为前台服务,并通过stopForeground()停止前台服务的状态。

前台服务适用于需要持续运行的任务(如音乐播放、位置跟踪等),但需要确保用户能够感知到服务的运行(通过通知)。

5. 服务生命周期的异常处理

在实际开发中,服务可能会因为系统资源限制或用户操作(如强制停止应用)而被销毁。为了避免服务被意外销毁,可以使用以下策略:

  • 前台服务:将重要的后台任务提升为前台服务,以提高其优先级。
  • 持久化任务:在onStartCommand()中返回START_STICKYSTART_REDELIVER_INTENT,以便在服务被销毁后重新创建。
  • 监听系统事件:在服务的生命周期回调中,妥善处理系统事件(如低内存通知),以确保服务的稳定性。

五、Service通信与优先级

在Android应用开发中,Service不仅负责在后台执行任务,还需要与其他组件(如Activity、BroadcastReceiver等)进行通信,以实现数据的交换和控制的传递。此外,合理设置Service的优先级可以确保其在系统资源紧张时仍能够正常运行。本部分将深入探讨Service的通信机制和优先级设置。

1. Service的通信机制

Service与其他组件之间的通信主要通过以下几种方式进行:

a. 绑定服务(Bound Service)

绑定服务允许组件通过IBinder接口与Service进行交互。具体来说,客户端可以使用bindService()方法来绑定到Service,并通过返回的IBinder对象调用Service的方法。

  • 实现绑定服务

    • Service需要重写onBind(Intent intent)方法,并返回一个IBinder对象。
    • 客户端通过bindService()方法绑定到Service,并在onServiceConnected()回调中获取IBinder对象。
  • 示例代码

    // Service端
    @Override
    public IBinder onBind(Intent intent) {return new MyBinder();
    }class MyBinder extends Binder {public void doSomething() {// 执行某些操作}
    }// 客户端
    Intent intent = new Intent(this, MyService.class);
    bindService(intent, connection, Context.BIND_AUTO_CREATE);private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder binder) {MyService.MyBinder myBinder = (MyService.MyBinder) binder;myBinder.doSomething();}@Overridepublic void onServiceDisconnected(ComponentName name) {// 处理服务断开连接的情况}
    };
    
b. 消息传递(Messenger)

使用Messenger可以在不同进程间进行消息传递,适用于跨进程通信。

  • 实现Messenger

    • Service创建一个Messenger对象,并通过onBind()方法将其传递给客户端。
    • 客户端通过Messenger发送消息,Service处理这些消息并进行响应。
  • 示例代码

    // Service端
    class IncomingHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_DO_SOMETHING:// 执行某些操作break;default:super.handleMessage(msg);}}
    }private final Messenger messenger = new Messenger(new IncomingHandler());@Override
    public IBinder onBind(Intent intent) {return messenger.getBinder();
    }// 客户端
    private Messenger mService = null;
    private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder binder) {mService = new Messenger(binder);Message msg = Message.obtain(null, MSG_DO_SOMETHING);try {mService.send(msg);} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onServiceDisconnected(ComponentName name) {mService = null;}
    };
    
c. 本地广播(LocalBroadcastManager)

使用LocalBroadcastManager可以在应用内部发送和接收广播,适合在Activity和Service之间进行通信。

  • 发送广播

    • 使用LocalBroadcastManager.getInstance(context).sendBroadcast(intent)发送广播。
  • 接收广播

    • 注册一个BroadcastReceiver来接收广播,并在onReceive()方法中处理接收到的Intent。
  • 示例代码

    // Service端
    Intent intent = new Intent("com.example.UPDATE_UI");
    intent.putExtra("data", "some data");
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);// Activity端
    private BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String data = intent.getStringExtra("data");// 更新UI或执行其他操作}
    };@Override
    protected void onStart() {super.onStart();LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter("com.example.UPDATE_UI"));
    }@Override
    protected void onStop() {super.onStop();LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
    }
    

2. Service的优先级设置

在Android中,Service的优先级主要通过设置Service的类型和属性来控制。合理设置Service的优先级可以确保其在系统资源紧张时不会被轻易杀死。

a. 前台服务(Foreground Service)

前台服务是优先级最高的Service类型,适用于需要持续运行且用户可见的任务,如音乐播放、导航等。前台服务需要显示一个持续的Notification,以告知用户服务正在运行。

  • 将Service设置为前台服务

    • 在Service的onStartCommand()方法中调用startForeground(int id, Notification notification),传入一个唯一的ID和一个Notification对象。
  • 示例代码

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID).setContentTitle("Foreground Service").setContentText("Service is running...").setSmallIcon(R.drawable.ic_notification).build();startForeground(1, notification);return START_STICKY;
    }
    
b. START_STICKY、START_NOT_STICKY和START_REDELIVER_INTENT

onStartCommand()方法中,可以通过返回不同值来控制Service在被系统杀死后的行为。

  • START_STICKY

    • 如果Service在执行任务时被系统杀死,系统会自动重新创建该Service,并调用onStartCommand()方法,但不会重新传递之前的Intent。
  • START_NOT_STICKY

    • 如果Service在执行任务时被系统杀死,且没有pending的启动命令,系统将不会自动重新创建该Service。
  • START_REDELIVER_INTENT

    • 如果Service在执行任务时被系统杀死,系统会自动重新创建该Service,并尝试重新传递最近一次的Intent。
  • 示例代码

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {// 执行任务return START_STICKY; // 根据需求选择合适的返回值
    }
    

3. 优先级与性能考虑

在设置Service优先级时,需要权衡用户体验和系统性能。

  • 前台服务

    • 优点:高优先级,不易被系统杀死,适用于重要任务。
    • 缺点:必须显示Notification,可能打扰用户;消耗更多系统资源。
  • 后台服务

    • 优点:节省系统资源,不影响用户体验。
    • 缺点:在系统资源紧张时容易被杀死,任务可能无法完成。

因此,在设计Service时,应根据具体需求选择合适的优先级设置,并确保不会对用户造成不必要的干扰。


http://www.ppmy.cn/news/1561964.html

相关文章

【Ubuntu】如何设置 Ubuntu 自动每日更新:轻松保持系统安全

如何设置 Ubuntu 自动每日更新&#xff1a;轻松保持系统安全 大家好&#xff01;今天我们来聊一个非常实用的话题——如何让 Ubuntu 系统自动每日更新。如果你是一个 Ubuntu 用户&#xff0c;尤其是服务器管理员&#xff0c;你可能会经常遇到这样的问题&#xff1a;系统需要频…

西电-算法分析-研究生课程复习笔记

24年秋的应该是张老师最后一次用卷面考试&#xff0c;他说以后这节课的期末考试都是在OJ上刷题了张老师上课还挺有意思的&#xff0c;上完之后能学会独立地思考算法设计问题了。整节课都在强调规模压缩这个概念&#xff0c;考试也是考个人对这些的理解&#xff0c;还挺好玩的哈…

计算机网络——网络层-IPV4相关技术

一、网络地址转换NAT • 网络地址转换 NAT 方法于1994年提出。 • 需要在专用网连接到因特网的路由器上安装 NAT 软件。装有 NAT 软件的路由器叫做 NAT路由器&#xff0c;它至少有一个有效的外部全球地址 IPG。 • 所有使用本地地址的主机在和外界通信时都要在 NAT 路由器上将…

服务器 CPU 消耗过高是什么原因?

服务器是一种计算机系统&#xff0c;它为网络上的其他设备或计算机提供服务和资源。CPU(中央处理器)是服务器的大脑&#xff0c;负责处理指令和管理硬件和软件资源。CPU 的性能和功能直接影响服务器处理工作负载和提供可靠服务的能力。 服务器管理员必须谨慎选择满足服务器需求…

堆排序+选择排序详解

目录 1.选择排序的定义 2.选择排序的优缺点 2.1优点 2.2缺点 3.思考 4.优化后的选择排序的实现 5.选择排序的代码 6.堆排序 7.向上/向下调整算法 8. 向下向上调整代码 9.堆排序代码 1.选择排序的定义 选择排序(SelectSort)&#xff0c;以第一个为开始值&#xff0c…

rust学习——环境搭建

rust安装&#xff1a;https://kaisery.github.io/trpl-zh-cn/ch01-01-installation.html 1、vscode装插件&#xff1a; toml语法支持 依赖管理 rust语法支持 2、创建demo 3、查看目录 4、执行文件的几种方式&#xff1a; rust安装&#xff1a;https://www.rust-lang.org/z…

移动 web :平面转换,渐变

平面转换 平移效果 平移实现居中效果 双开门案例 &#xff1a; 设置父级背景图片&#xff0c;子级两张图片在父级上&#xff0c;分别占据 50%的宽度设置鼠标悬停效果&#xff0c;鼠标悬停&#xff0c;那么两张子级图片分别左右平移&#xff0c;而且设置过渡效果再在父级中设置溢…

Linux(Centos 7.6)命令详解:mkdir

1.命令作用 如果目录还不存在&#xff0c;则创建目录(Create the DIRECTORY, if they do not already exist.) 2.命令语法 Usage: mkdir [OPTION]... DIRECTORY... 3.参数详解 OPTION: -m, --modeMODE&#xff0c;创建新目录同时设置权限模式-p, --parents&#xff0c;创…