Android 5.0的调度作业JobScheduler

2023-11-05 12:32

本文主要是介绍Android 5.0的调度作业JobScheduler,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://blog.csdn.net/cuiran/article/details/42805057

Android 5.0 提供了一个新的 JobScheduler API,它允许您通过为系统定义要在以后的某个时间或在指定的条件下(例如,当设备在充电时)异步运行的作业来优化电池寿命。

首先看一下官方JobScheduler的API  https://developer.android.com/reference/android/app/job/JobScheduler.html

This is an API for scheduling various types of jobs against the framework that will be executed in your application's own process.

这是一个API调度框架,将在您的应用程序的进程中执行的工作

See JobInfo for more description of the types of jobs that can be run and how to construct them. You will construct these JobInfo objects and pass them to the JobScheduler with schedule(JobInfo). When the criteria declared are met, the system will execute this job on your application's JobService. You identify which JobService is meant to execute the logic for your job when you create the JobInfo with JobInfo.Builder(int, android.content.ComponentName).

看到Jobinfo的更多的描述类型的工作可以运行,以及如何构建。你可以构造这些JobInfo对象,并且使用schedule(JobInfo)在JobScheduler。

当符合标准声明,系统将执行调度在你的应用程序Jobservice。

The framework will be intelligent about when you receive your callbacks, and attempt to batch and defer them as much as possible. Typically if you don't specify a deadline on your job, it can be run at any moment depending on the current state of the JobScheduler's internal queue, however it might be deferred as long as until the next time the device is connected to a power source.

You do not instantiate this class directly; instead, retrieve it through Context.getSystemService(Context.JOB_SCHEDULER_SERVICE).


作业调度在下列情况下非常有用:

  • 应用具有您可以推迟的非面向用户的工作。
  • 应用具有当插入设备时您希望优先执行的工作。
  • 应用具有需要访问网络或 Wi-Fi 连接的任务。
  • 应用具有您希望作为一个批次定期运行的许多任务。

工作单元由一个 JobInfo 对象进行封装。此对象指定了调度条件。官方的API如下

Public Methods
int describeContents()
Describe the kinds of special objects contained in this Parcelable's marshalled representation.
int getBackoffPolicy()
One of either  BACKOFF_POLICY_EXPONENTIAL, or  BACKOFF_POLICY_LINEAR, depending on which criteria you set when creating this job.
PersistableBundle getExtras()
Bundle of extras which are returned to your application at execution time.
int getId()
Unique job id associated with this class.
long getInitialBackoffMillis()
The amount of time the JobScheduler will wait before rescheduling a failed job.
long getIntervalMillis()
Set to the interval between occurrences of this job.
long getMaxExecutionDelayMillis()
See  setOverrideDeadline(long).
long getMinLatencyMillis()
Set for a job that does not recur periodically, to specify a delay after which the job will be eligible for execution.
int getNetworkType()
One of  NETWORK_TYPE_ANYNETWORK_TYPE_NONE, or  NETWORK_TYPE_UNMETERED.
ComponentName getService()
Name of the service endpoint that will be called back into by the JobScheduler.
boolean isPeriodic()
Track whether this job will repeat with a given period.
boolean isPersisted()
boolean isRequireCharging()
Whether this job needs the device to be plugged in.
boolean isRequireDeviceIdle()
Whether this job needs the device to be in an Idle maintenance window.
String toString()
Returns a string containing a concise, human-readable description of this object.
void writeToParcel( Parcel out, int flags)
Flatten this object in to a Parcel.

使用 JobInfo.Builder 类配置调度的任务应当如何运行。您可以将任务调度为在特定的条件下运行,例如:

  • 当设备充电时启动
  • 当设备连接到不限流量网络时启动
  • 当设备空闲时启动
  • 在特定的截止期限之前或以最小的延迟完成

例如,您可以添加如下代码以在不限流量网络上运行您的任务:

<span class="typ" style="color: rgb(102, 0, 102);">JobInfo</span><span class="pln" style="color: rgb(0, 0, 0);"> uploadTask </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">JobInfo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">Builder</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">mJobId</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);">mServiceComponent </span><span class="com">/* JobService component */</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"></span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">setRequiredNetworkCapabilities</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">JobInfo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">NetworkType</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">UNMETERED</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"></span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">build</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="typ" style="color: rgb(102, 0, 102);">JobScheduler</span><span class="pln" style="color: rgb(0, 0, 0);"> jobScheduler </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"></span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">JobScheduler</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> context</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">getSystemService</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="typ" style="color: rgb(102, 0, 102);">Context</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">JOB_SCHEDULER_SERVICE</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
jobScheduler</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">schedule</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">uploadTask</span><span class="pun" style="color: rgb(102, 102, 0);">);</span>

如果设备具有稳定的电源(也就是说,它已插入了 2 分钟以上并且电池处于健康水平),则系统将运行任何已就绪可运行的已调度作业,即使作业的截止期限尚未到期也是如此。

这里可以在看一下官方给出的 JobService API

Entry point for the callback from the JobScheduler.

This is the base class that handles asynchronous requests that were previously scheduled. You are responsible for overriding onStartJob(JobParameters), which is where you will implement your job logic.

This service executes each incoming job on a Handler running on your application's main thread. This means that you must offload your execution logic to another thread/handler/AsyncTask of your choosing. Not doing so will result in blocking any future callbacks from the JobManager - specifically onStopJob(android.app.job.JobParameters), which is meant to inform you that the scheduling requirements are no longer being met.

所提供的方法如下

final void jobFinished( JobParameters params, boolean needsReschedule)
Callback to inform the JobManager you've finished executing.   当完成执行后,通知调度管理器
abstract boolean onStartJob( JobParameters params)
Override this method with the callback logic for your job.
abstract boolean onStopJob( JobParameters params)
This method is called if the system has determined that you must stop execution of your job even before you've had a chance to call  jobFinished(JobParameters, boolean).

下面可以看一下官方给出的一个sample

运行效果如下


Activity如下

[java]  view plain copy
在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * Copyright 2013 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package com.example.android.jobscheduler;  
  18.   
  19. import android.app.Activity;  
  20. import android.app.job.JobInfo;  
  21. import android.app.job.JobParameters;  
  22. import android.app.job.JobScheduler;  
  23. import android.content.ComponentName;  
  24. import android.content.Context;  
  25. import android.content.Intent;  
  26. import android.content.res.Resources;  
  27. import android.os.Bundle;  
  28. import android.os.Handler;  
  29. import android.os.Message;  
  30. import android.os.Messenger;  
  31. import android.text.TextUtils;  
  32. import android.view.View;  
  33. import android.widget.CheckBox;  
  34. import android.widget.EditText;  
  35. import android.widget.RadioButton;  
  36. import android.widget.TextView;  
  37. import android.widget.Toast;  
  38.   
  39. import com.example.android.jobscheduler.service.TestJobService;  
  40.   
  41. public class MainActivity extends Activity {  
  42.   
  43.     private static final String TAG = "MainActivity";  
  44.   
  45.     public static final int MSG_UNCOLOUR_START = 0;  
  46.     public static final int MSG_UNCOLOUR_STOP = 1;  
  47.     public static final int MSG_SERVICE_OBJ = 2;  
  48.   
  49.     @Override  
  50.     public void onCreate(Bundle savedInstanceState) {  
  51.         super.onCreate(savedInstanceState);  
  52.         setContentView(R.layout.sample_main);  
  53.         Resources res = getResources();  
  54.         defaultColor = res.getColor(R.color.none_received);  
  55.         startJobColor = res.getColor(R.color.start_received);  
  56.         stopJobColor = res.getColor(R.color.stop_received);  
  57.   
  58.         // Set up UI.  
  59.         mShowStartView = (TextView) findViewById(R.id.onstart_textview);  
  60.         mShowStopView = (TextView) findViewById(R.id.onstop_textview);  
  61.         mParamsTextView = (TextView) findViewById(R.id.task_params);  
  62.         mDelayEditText = (EditText) findViewById(R.id.delay_time);  
  63.         mDeadlineEditText = (EditText) findViewById(R.id.deadline_time);  
  64.         mWiFiConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_unmetered);  
  65.         mAnyConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_any);  
  66.         mRequiresChargingCheckBox = (CheckBox) findViewById(R.id.checkbox_charging);  
  67.         mRequiresIdleCheckbox = (CheckBox) findViewById(R.id.checkbox_idle);  
  68.         mServiceComponent = new ComponentName(this, TestJobService.class);  
  69.         // Start service and provide it a way to communicate with us.  
  70.         Intent startServiceIntent = new Intent(this, TestJobService.class);  
  71.         startServiceIntent.putExtra("messenger"new Messenger(mHandler));  
  72.         startService(startServiceIntent);  
  73.     }  
  74.     // UI fields.  
  75.     int defaultColor;  
  76.     int startJobColor;  
  77.     int stopJobColor;  
  78.   
  79.     private TextView mShowStartView;  
  80.     private TextView mShowStopView;  
  81.     private TextView mParamsTextView;  
  82.     private EditText mDelayEditText;  
  83.     private EditText mDeadlineEditText;  
  84.     private RadioButton mWiFiConnectivityRadioButton;  
  85.     private RadioButton mAnyConnectivityRadioButton;  
  86.     private CheckBox mRequiresChargingCheckBox;  
  87.     private CheckBox mRequiresIdleCheckbox;  
  88.   
  89.     ComponentName mServiceComponent;  
  90.     /** Service object to interact scheduled jobs. */  
  91.     TestJobService mTestService;  
  92.   
  93.     private static int kJobId = 0;  
  94.   
  95.     Handler mHandler = new Handler(/* default looper */) {  
  96.         @Override  
  97.         public void handleMessage(Message msg) {  
  98.             switch (msg.what) {  
  99.                 case MSG_UNCOLOUR_START:  
  100.                     mShowStartView.setBackgroundColor(defaultColor);  
  101.                     break;  
  102.                 case MSG_UNCOLOUR_STOP:  
  103.                     mShowStopView.setBackgroundColor(defaultColor);  
  104.                     break;  
  105.                 case MSG_SERVICE_OBJ:  
  106.                     mTestService = (TestJobService) msg.obj;  
  107.                     mTestService.setUiCallback(MainActivity.this);  
  108.             }  
  109.         }  
  110.     };  
  111.   
  112.     private boolean ensureTestService() {  
  113.         if (mTestService == null) {  
  114.             Toast.makeText(MainActivity.this"Service null, never got callback?",  
  115.                     Toast.LENGTH_SHORT).show();  
  116.             return false;  
  117.         }  
  118.         return true;  
  119.     }  
  120.   
  121.     /** 
  122.      * UI onclick listener to schedule a job. What this job is is defined in 
  123.      * TestJobService#scheduleJob(). 
  124.      */  
  125.     public void scheduleJob(View v) {  
  126.         if (!ensureTestService()) {  
  127.             return;  
  128.         }  
  129.   
  130.         JobInfo.Builder builder = new JobInfo.Builder(kJobId++, mServiceComponent);  
  131.   
  132.         String delay = mDelayEditText.getText().toString();  
  133.         if (delay != null && !TextUtils.isEmpty(delay)) {  
  134.             builder.setMinimumLatency(Long.valueOf(delay) * 1000);  
  135.         }  
  136.         String deadline = mDeadlineEditText.getText().toString();  
  137.         if (deadline != null && !TextUtils.isEmpty(deadline)) {  
  138.             builder.setOverrideDeadline(Long.valueOf(deadline) * 1000);  
  139.         }  
  140.         boolean requiresUnmetered = mWiFiConnectivityRadioButton.isChecked();  
  141.         boolean requiresAnyConnectivity = mAnyConnectivityRadioButton.isChecked();  
  142.         if (requiresUnmetered) {  
  143.             builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);  
  144.         } else if (requiresAnyConnectivity) {  
  145.             builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);  
  146.         }  
  147.         builder.setRequiresDeviceIdle(mRequiresIdleCheckbox.isChecked());  
  148.         builder.setRequiresCharging(mRequiresChargingCheckBox.isChecked());  
  149.   
  150.         mTestService.scheduleJob(builder.build());  
  151.   
  152.     }  
  153.     /** 
  154.      * cancel All jobs 
  155.      * @param v 
  156.      */  
  157.     public void cancelAllJobs(View v) {  
  158.         JobScheduler tm =  
  159.                 (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);  
  160.         tm.cancelAll();  
  161.     }  
  162.   
  163.     /** 
  164.      * UI onclick listener to call jobFinished() in our service. 
  165.      */  
  166.     public void finishJob(View v) {  
  167.         if (!ensureTestService()) {  
  168.             return;  
  169.         }  
  170.         mTestService.callJobFinished();  
  171.         mParamsTextView.setText("");  
  172.     }  
  173.   
  174.     /** 
  175.      * Receives callback from the service when a job has landed 
  176.      * on the app. Colours the UI and post a message to 
  177.      * uncolour it after a second. 
  178.      */  
  179.     public void onReceivedStartJob(JobParameters params) {  
  180.         mShowStartView.setBackgroundColor(startJobColor);  
  181.         Message m = Message.obtain(mHandler, MSG_UNCOLOUR_START);  
  182.         mHandler.sendMessageDelayed(m, 1000L); // uncolour in 1 second.  
  183.         mParamsTextView.setText("Executing: " + params.getJobId() + " " + params.getExtras());  
  184.     }  
  185.   
  186.     /** 
  187.      * Receives callback from the service when a job that 
  188.      * previously landed on the app must stop executing. 
  189.      * Colours the UI and post a message to uncolour it after a 
  190.      * second. 
  191.      */  
  192.     public void onReceivedStopJob() {  
  193.         mShowStopView.setBackgroundColor(stopJobColor);  
  194.         Message m = Message.obtain(mHandler, MSG_UNCOLOUR_STOP);  
  195.         mHandler.sendMessageDelayed(m, 2000L); // uncolour in 1 second.  
  196.         mParamsTextView.setText("");  
  197.     }  
  198. }  
 然后新建一个类继承JobService

[java]  view plain copy
在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * Copyright 2014 Google Inc. 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package com.example.android.jobscheduler.service;  
  18.   
  19. import android.app.job.JobInfo;  
  20. import android.app.job.JobScheduler;  
  21. import android.app.job.JobParameters;  
  22. import android.app.job.JobService;  
  23. import android.content.Context;  
  24. import android.content.Intent;  
  25. import android.os.Message;  
  26. import android.os.Messenger;  
  27. import android.os.RemoteException;  
  28. import android.util.Log;  
  29.   
  30. import com.example.android.jobscheduler.MainActivity;  
  31.   
  32. import java.util.LinkedList;  
  33.   
  34.   
  35. /** 
  36.  * Service to handle callbacks from the JobScheduler. Requests scheduled with the JobScheduler 
  37.  * ultimately land on this service's "onStartJob" method. Currently all this does is post a message 
  38.  * to the app's main activity to change the state of the UI. 
  39.  */  
  40. public class TestJobService extends JobService {  
  41.     private static final String TAG = "SyncService";  
  42.   
  43.     @Override  
  44.     public void onCreate() {  
  45.         super.onCreate();  
  46.         Log.i(TAG, "Service created");  
  47.     }  
  48.   
  49.     @Override  
  50.     public void onDestroy() {  
  51.         super.onDestroy();  
  52.         Log.i(TAG, "Service destroyed");  
  53.     }  
  54.   
  55.     /** 
  56.      * When the app's MainActivity is created, it starts this service. This is so that the 
  57.      * activity and this service can communicate back and forth. See "setUiCalback()" 
  58.      */  
  59.     @Override  
  60.     public int onStartCommand(Intent intent, int flags, int startId) {  
  61.         Messenger callback = intent.getParcelableExtra("messenger");  
  62.         Message m = Message.obtain();  
  63.         m.what = MainActivity.MSG_SERVICE_OBJ;  
  64.         m.obj = this;  
  65.         try {  
  66.             callback.send(m);  
  67.         } catch (RemoteException e) {  
  68.             Log.e(TAG, "Error passing service object back to activity.");  
  69.         }  
  70.         return START_NOT_STICKY;  
  71.     }  
  72.   
  73.     @Override  
  74.     public boolean onStartJob(JobParameters params) {  
  75.         // We don't do any real 'work' in this sample app. All we'll  
  76.         // do is track which jobs have landed on our service, and  
  77.         // update the UI accordingly.  
  78.         jobParamsMap.add(params);  
  79.         if (mActivity != null) {  
  80.             mActivity.onReceivedStartJob(params);  
  81.         }  
  82.         Log.i(TAG, "on start job: " + params.getJobId());  
  83.         return true;  
  84.     }  
  85.   
  86.     @Override  
  87.     public boolean onStopJob(JobParameters params) {  
  88.         // Stop tracking these job parameters, as we've 'finished' executing.  
  89.         jobParamsMap.remove(params);  
  90.         if (mActivity != null) {  
  91.             mActivity.onReceivedStopJob();  
  92.         }  
  93.         Log.i(TAG, "on stop job: " + params.getJobId());  
  94.         return true;  
  95.     }  
  96.   
  97.     MainActivity mActivity;  
  98.     private final LinkedList<JobParameters> jobParamsMap = new LinkedList<JobParameters>();  
  99.   
  100.     public void setUiCallback(MainActivity activity) {  
  101.         mActivity = activity;  
  102.     }  
  103.   
  104.     /** Send job to the JobScheduler. */  
  105.     public void scheduleJob(JobInfo t) {  
  106.         Log.d(TAG, "Scheduling job");  
  107.         JobScheduler tm =  
  108.                 (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);  
  109.         tm.schedule(t);  
  110.     }  
  111.   
  112.     /** 
  113.      * Not currently used, but as an exercise you can hook this 
  114.      * up to a button in the UI to finish a job that has landed 
  115.      * in onStartJob(). 
  116.      */  
  117.     public boolean callJobFinished() {  
  118.         JobParameters params = jobParamsMap.poll();  
  119.         if (params == null) {  
  120.             return false;  
  121.         } else {  
  122.             jobFinished(params, false);  
  123.             return true;  
  124.         }  
  125.     }  
  126.   
  127. }  

具体详细代码可以参考下载的sdk里面


这篇关于Android 5.0的调度作业JobScheduler的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/349902

相关文章

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR