首页 文章 精选 留言 我的

精选列表

搜索[官方],共10000篇文章
优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:后台加载数据之处理CursorLoader的查询结果

原文地址:http://android.xsoftlab.net/training/load-data-background/handle-results.html 就像上节课所说的,我们应该在onCreateLoader()内使用CursorLoader来加载数据。那么在数据加载完毕之后,加载结果会通过LoaderCallbacks.onLoadFinished()方法传回到实现类中。该方法的其中一个参数为包含查询结果的Cursor对象。你可以通过这个对象来更新UI数据或者用它来做进一步的操作。 除了onCreateLoader()及onLoadFinished()这两个方法之外,还应当实现onLoaderReset()方法。这个方法会在上面返回的Cursor对象所关联的数据发生变化时调用。如果数据发生了变化,那么Android框架会重新进行查询。 处理查询结果 为了显示Cursor对象中的数据,这里需要实现AdapterView的相关方法以及CursorAdapter的相关方法。系统会自动的将Cursor中的数据转换到View上。 你可以在展示数据之前将数据与Adapter对象进行关联,这样的话系统才会自动的更新View: public String[] mFromColumns = { DataProviderContract.IMAGE_PICTURENAME_COLUMN }; public int[] mToFields = { R.id.PictureName }; // Gets a handle to a List View ListView mListView = (ListView) findViewById(R.id.dataList); /* * Defines a SimpleCursorAdapter for the ListView * */ SimpleCursorAdapter mAdapter = new SimpleCursorAdapter( this, // Current context R.layout.list_item, // Layout for a single row null, // No Cursor yet mFromColumns, // Cursor columns to use mToFields, // Layout fields to use 0 // No flags ); // Sets the adapter for the view mListView.setAdapter(mAdapter); ... /* * Defines the callback that CursorLoader calls * when it's finished its query */ @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { ... /* * Moves the query results into the adapter, causing the * ListView fronting this adapter to re-display */ mAdapter.changeCursor(cursor); } 移除旧的Cursor引用 CursorLoader会在Cursor处于无效状态时对其进行重置。这种事件会经常发生,因为Cursor所关联的数据会经常发生变化。在重新查询之前,系统会调用所实现的onLoaderReset()方法。在该方法内,应将当前Cursor的所持有的引用置空,以防止内存泄露。一旦onLoaderReset()方法执行完毕,CursorLoader就会重新进行查询。 /* * Invoked when the CursorLoader is being reset. For example, this is * called if the data in the provider changes and the Cursor becomes stale. */ @Override public void onLoaderReset(Loader<Cursor> loader) { /* * Clears out the adapter's reference to the Cursor. * This prevents memory leaks. */ mAdapter.changeCursor(null); }

优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:键盘输入处理之指定输入的类型

原文地址:http://android.xsoftlab.net/training/keyboard-input/index.html 引言 在文本框接收到焦点时,Android系统会在屏幕上显示一个软键盘。为了提供良好的用户体验,你可以指定相关输入类型的特性,以及输入法应当如何展现。 除了屏幕上的软键盘之外,Android还支持实体键盘,所以APP如何与各种类型的键盘交互这件事情,就变得很重要了。 指定输入的类型 每一个文本框必定只有一种输入类型,比如一个电子邮件地址,一个电话号码或者是常规文本。所以为每一个文本框指定输入类型就变得很重要,这样的话系统才会显示正确的输入法。 你可以指定比如输入方法所提供的拼写建议、首字母大写、以及输入法右下角按钮的行为(Done或者Next)。这节课主要介绍如何指定这些特性。 指定键盘类型 你应该总是为文本框声明输入类型,通过android:inputType属性可以为文本框添加输入类型。 比如,如果你希望文本框的输入类型为电话号码,可以使用”phone”: <EditText android:id="@+id/phone" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/phone_hint" android:inputType="phone" /> 或者如果文本框主要是用于输入密码的,可以使用”textPassword”隐藏用户的输入文本: <EditText android:id="@+id/password" android:hint="@string/password_hint" android:inputType="textPassword" ... /> android:inputType含有多种指定的输入类型,并且一些值可以组合使用。 开启拼写检查与其它功能 android:inputType属性允许你可以为输入类型指定多种行为。更重要的一点是,如果文本框的重点在基础文本输入上(如文本消息),你应当使用”textAutoCorrect”开启拼写检查。 你还可以为android:inputType属性指定多种不同的行为以及输入类型。比如,下面的例子就展示了如何同时开启首字母大写以及拼写检查的功能: <EditText android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:inputType= "textCapSentences|textAutoCorrect" ... /> 指定输入法按钮的行为 大多数的输入法都在右下角提供了一个用户功能按钮,这对于当前的文本框来说是极为恰当的。在默认情况下,系统使用这个按钮来实现Next或者Done功能。除非你的文本框允许多行情况的出现(比如使用了android:inputType=”textMultiLine”)。在这种情况下,该功能按钮是一个回车按钮。然而,你可以指定一些更加符合你文本框的特别功能,比如Send或Go。 为了指定键盘的功能按钮,需要使用属性android:imeOptions,并需要执行比如”actionSend”或”actionSearch”之类的值: <EditText android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/search_hint" android:inputType="text" android:imeOptions="actionSend" /> 接下来可以通过TextView.OnEditorActionListener来监听功能按钮的按下事件,并需要在该监听器内响应正确的IME功能ID,该ID定义与EditorInfo中,比如下面使用的就是IME_ACTION_SEND: EditText editText = (EditText) findViewById(R.id.search); editText.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { boolean handled = false; if (actionId == EditorInfo.IME_ACTION_SEND) { sendMessage(); handled = true; } return handled; } });

优秀的个人博客,低调大师

CNCFxLFOSSA云原生专业人才培养计划,免费申请官方基金会认证学习及考试机会

CNCFxLFOSSA云原生专业人才培养计划 CNCF X LFOSSA Cloud Native Talent Developement Program 在一个不断扩大的云原生服务市场,人才短缺是企业HR永恒的烦恼。经验告诉我们,企业IT人员,例如项目经理和产品经理,他们并不一定要有计算机相关学位,但是一个认可的云原生资格证书是必不可少的。针对这个需求,CNCF推出了KCNA (Kubernetes And Cloud Native Associate)认证和培训,目的是赋予认证者全面的K8s和云原生知识,同时拥有足够的能力分析问题和解决问题。 With growing cloud-native services market, talent shortage is always an pain point to HR of the enterprises. From our experience, enterprise IT personnel, such as Project Managers and Product Managers, don't need to have a Computer Science-related Degree, but an accredited cloud-native qualification is essential for them to equip with corresponding skills for everyday work. Therefore, CNCF has launched the KCNA (Kubernetes And Cloud Native Associate) certification and training, which aims to let KCNA certified holders get comprehensive K8s and cloud native knowledge, and with sufficient capabilty to analyze and solve problems. 为了在云原生业界培养更多开源人才,CNCF和LFOSSA合作一起举办CNCFXLFOSSA云原生专业人才培养计划,填妥以下的表格,表达你对你云原生事业的规划和热诚!成功申请人士将获得免费参加KCNA+准备课程LFS250(价值:人民币1988元)的机会! In order to develop more talents in Cloud Native Industry, CNCF and Linux Foundation Open Source Software Academy launch the CNCF X LFOSSA Cloud Native Talent Developement Program in China. To apply for this program, please fill out and submit the online form, and show us your enthuastism to your Cloud Native career as well as your career planning. LFOSSA will sponsor the successful applicants to take KCNA certification exam and the online selfpaced course, LFS250 to prepare for this certification. 我们将在6月8日下午进行KCNA发布会,更多详情给按这里。 Who should participate? 谁应该参加? HR Manager 人力资源经理 IT Manager IT 经理 IT Sales IT 销售人员 IT Sales Engineer IT 销售工程师 IT Pre-Sales IT 售前人员 IT Consultant IT 顾问 Prodcut Manager 产品经理 Project Manager 项目经理 Developers who are new to Cloud Native希望加入原生行列的开发人员 Training Organizations and Instructors 培训机构及培训导师 Country 国家: Mainland China, Taiwan, Hong Kong, Macau & Asia Pacific 中国,台湾,香港,澳门及亚太区等 Important Dates 重要时间点: Application Deadline: Jun 24, 2022 Notification and Annoucement of Successful Applicants: 3rd week of July, 2022 Time for Successful Applicants to take KCNA: July - Dec, 2022 申请截止日:6月24日 公布时间:7月第三周 成功申请人参与考试时间:8月至12月底 Click here to fill out the application form 按此填写申请表格

优秀的个人博客,低调大师

CNCFxLFOSSA云原生专业人才培养计划,免费申请基金会官方认证学习及考试机会

CNCFxLFOSSA云原生专业人才培养计划 CNCF X LFOSSA Cloud Native Talent Developement Program 在一个不断扩大的云原生服务市场,人才短缺是企业HR永恒的烦恼。经验告诉我们,企业IT人员,例如项目经理和产品经理,他们并不一定要有计算机相关学位,但是一个认可的云原生资格证书是必不可少的。针对这个需求,CNCF推出了KCNA (Kubernetes And Cloud Native Associate)认证和培训,目的是赋予认证者全面的K8s和云原生知识,同时拥有足够的能力分析问题和解决问题。 With growing cloud-native services market, talent shortage is always an pain point to HR of the enterprises. From our experience, enterprise IT personnel, such as Project Managers and Product Managers, don't need to have a Computer Science-related Degree, but an accredited cloud-native qualification is essential for them to equip with corresponding skills for everyday work. Therefore, CNCF has launched the KCNA (Kubernetes And Cloud Native Associate) certification and training, which aims to let KCNA certified holders get comprehensive K8s and cloud native knowledge, and with sufficient capabilty to analyze and solve problems. 为了在云原生业界培养更多开源人才,CNCF和LFOSSA合作一起举办CNCFXLFOSSA云原生专业人才培养计划,填妥以下的表格,表达你对你云原生事业的规划和热诚!成功申请人士将获得免费参加KCNA+准备课程LFS250(价值:人民币1988元)的机会! In order to develop more talents in Cloud Native Industry, CNCF and Linux Foundation Open Source Software Academy launch the CNCF X LFOSSA Cloud Native Talent Developement Program in China. To apply for this program, please fill out and submit the online form, and show us your enthuastism to your Cloud Native career as well as your career planning. LFOSSA will sponsor the successful applicants to take KCNA certification exam and the online selfpaced course, LFS250 to prepare for this certification. 我们将在6月8日下午进行KCNA发布会,更多详情给按这里。 Who should participate? 谁应该参加? HR Manager 人力资源经理 IT Manager IT 经理 IT Sales IT 销售人员 IT Sales Engineer IT 销售工程师 IT Pre-Sales IT 售前人员 IT Consultant IT 顾问 Prodcut Manager 产品经理 Project Manager 项目经理 Developers who are new to Cloud Native希望加入原生行列的开发人员 Training Organizations and Instructors 培训机构及培训导师 Country 国家: Mainland China, Taiwan, Hong Kong, Macau & Asia Pacific 中国,台湾,香港,澳门及亚太区等 Important Dates 重要时间点: Application Deadline: Jun 24, 2022 Notification and Annoucement of Successful Applicants: 3rd week of July, 2022 Time for Successful Applicants to take KCNA: July - Dec, 2022 申请截止日:6月24日 公布时间:7月第三周 成功申请人参与考试时间:8月至12月底 Click here to fill out the application form 按此填写申请表格

优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:线程执行操作之创建多线程管理器

原文地址:http://android.xsoftlab.net/training/multiple-threads/create-threadpool.html 上节课我们学习了如何定义一个任务。如果只是执行单次任务,那么刚刚所学的已经基本满足要求了。如果需要针对不同的数据执行同种任务,并且需要同一时间只能执行一项任务,那么IntentService可能会适合你。如果要使任务随着资源的可用而执行,或者同一时间需要运行多个任务,那么就需要专门管理这些线程了。Android系统为此提供了一个类,那就是传说中的ThreadPoolExecutor。它可以在线程可用时自动运行队列中的任务。如果要运行一个任务,只需要将任务添加到队列中即可。 ThreadPoolExecutor允许多个线程同时进行,所以应当确保代码是线程安全的。要确保可能会被多个线程访问到的变量被放在同步代码块中。这种方法可以防止一个线程正在读取一个变量的值,而另一个变量正在对这个变量写入新值的现象出现。通常情况下,这种现象会发生在静态变量中,但是也会发生在单例对象上。 定义线程池类 在该类内实例化一个ThreadPoolExecutor对象,并在该类内执行以下工作: 对线程池对象使用静态变量引用 在APP内通常只需要一个线程池对象的存在:为了对CPU资源或网络资源有一个单一的控制。如果含有不同的Runnable类型,你可能希望对每种类型都创建一个单独线程池,但是每种类型都还是单例类型。在这里的例子中,可以添加以下代码作为全局属性声明。 public class PhotoManager { ... static { ... // Creates a single static instance of PhotoManager sInstance = new PhotoManager(); } ... 使用私有构造方法: 私有的构造方法可以确保该类只有一个对象存在。 public class PhotoManager { ... /** * Constructs the work queues and thread pools used to download * and decode images. Because the constructor is marked private, * it's unavailable to other classes, even in the same package. */ private PhotoManager() { ... } 调用线程池的相关方法启动任务: 在线程池类内定义一个可以向线程池队列中添加任务的方法。 public class PhotoManager { ... // Called by the PhotoView to get a photo static public PhotoTask startDownload( PhotoView imageView, boolean cacheFlag) { ... // Adds a download task to the thread pool for execution sInstance. mDownloadThreadPool. execute(downloadTask.getHTTPDownloadRunnable()); ... } 在构造方法中实例化一个Handler对象,并将其连接到UI线程:Handler允许安全的调用比如View这种UI对象。大多数的UI对象只允许被UI线程访问。 private PhotoManager() { ... // Defines a Handler object that's attached to the UI thread mHandler = new Handler(Looper.getMainLooper()) { /* * handleMessage() defines the operations to perform when * the Handler receives a new Message to process. */ @Override public void handleMessage(Message inputMessage) { ... } ... } } 确定线程池参数 如果要实例化ThreadPoolExecutor对象,需要用到以下值: 线程池的初始值以及最大值: 线程数量的初始值用于指定池子的初始大小,最大值代表了该线程池所允许开放的最大并发数量。线程池中的线程数量取决于设备的可用核心数。这个值与当前的设备颇有关系: public class PhotoManager { ... /* * Gets the number of available cores * (not always the same as the maximum number of cores) */ private static int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors(); } 这个值可能不能够反映设备的物理核心数量;在一些设备上,核心是否可用取决于系统是否加载。对于这些设备,availableProcessors()返回了当前的活跃核心数量,这个值可能要比真实的总核心数要低。 存活时长及单位 线程在被关闭之间的闲置时长。这个时长由时间单元值负责解释,这些时间单位常量被定义在类TimeUnit中。 任务队列 一个持有Runnable对象的队列。为了启动线程中的执行代码,线程池管理器采用了先进先出的管理原则。在创建线程池之前需要提供一个这样的队列,使用任何实现了BlockingQueue接口的类皆可。为了匹配到APP的要求,你可以选择适当的队列实现;学习更多它们的相关知识,请参见ThreadPoolExecutor的描述文档。这里的使用了LinkedBlockingQueue: public class PhotoManager { ... private PhotoManager() { ... // A queue of Runnables private final BlockingQueue<Runnable> mDecodeWorkQueue; ... // Instantiates the queue of Runnables as a LinkedBlockingQueue mDecodeWorkQueue = new LinkedBlockingQueue<Runnable>(); ... } ... } 线程池创建 创建一个线程池,只需调用ThreadPoolExecutor()实例化一个线程池管理器就好。它会创建并管理一组线程。因为线程池大小的初始值与最大值是相同的,所以ThreadPoolExecutor()会在初始化的时候创建出所指定的线程数量: private PhotoManager() { ... // Sets the amount of time an idle thread waits before terminating private static final int KEEP_ALIVE_TIME = 1; // Sets the Time Unit to seconds private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS; // Creates a thread pool manager mDecodeThreadPool = new ThreadPoolExecutor( NUMBER_OF_CORES, // Initial pool size NUMBER_OF_CORES, // Max pool size KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, mDecodeWorkQueue); }

优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:后台服务之响应IntentService的处理结果

原文地址:https://developer.android.com/training/run-background-service/report-status.html 这节课主要学习如何将IntentService中的执行结果返回给请求点。一种推荐的方式就是使用 LocalBroadcastManager来实现,它会将所广播的Intent限制在APP内部。 发送IntentService的处理结果 为了可以将IntentService的处理结果发送给其它组件,首先需要创建一个Intent对象,并将执行结果放入该Intent内。 接下来要做的就是:将刚才创建好的Intent通过LocalBroadcastManager.sendBroadcast()发送出去。但凡是对该Intent注册了的,那么发送该Intent都会收到结果。可以通过getInstance()获取LocalBroadcastManager的实例。 例子如下: public final class Constants { ... // Defines a custom Intent action public static final String BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST"; ... // Defines the key for the status "extra" in an Intent public static final String EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS"; ... } public class RSSPullService extends IntentService { ... /* * Creates a new Intent containing a Uri object * BROADCAST_ACTION is a custom Intent action */ Intent localIntent = new Intent(Constants.BROADCAST_ACTION) // Puts the status into the Intent .putExtra(Constants.EXTENDED_DATA_STATUS, status); // Broadcasts the Intent to receivers in this app. LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); ... } 下一步就是如何处理接收到的Intent对象了。 接收IntentService的处理结果 如果需要接收广播出来的Intent,那么就需要用到BroadcastReceiver了。在BroadcastReceiver的实现类中重写onReceive()方法。当LocalBroadcastManager将相应的Intent对象广播出来后,那么该方法就会被自动回调。 举个例子: // Broadcast receiver for receiving status updates from the IntentService private class ResponseReceiver extends BroadcastReceiver { // Prevents instantiation private DownloadStateReceiver() { } // Called when the BroadcastReceiver gets an Intent it's registered to receive @ public void onReceive(Context context, Intent intent) { ... /* * Handle Intents here. */ ... } } 一旦定义好了BroadcastReceiver,那么就可以为其定义指定的意图过滤器了。要做到这些,需要创建一个IntentFilter。下面的代码演示了如何定义一个过滤器: // Class that displays photos public class DisplayActivity extends FragmentActivity { ... public void onCreate(Bundle stateBundle) { ... super.onCreate(stateBundle); ... // The filter's action is BROADCAST_ACTION IntentFilter mStatusIntentFilter = new IntentFilter( Constants.BROADCAST_ACTION); // Adds a data filter for the HTTP scheme mStatusIntentFilter.addDataScheme("http"); 为了将BroadcastReceiver以及IntentFilter注册到系统,需要先获取LocalBroadcastManager的实例,然后再调用它的registerReceiver()方法。下面的代码演示了这个过程: // Instantiates a new DownloadStateReceiver DownloadStateReceiver mDownloadStateReceiver = new DownloadStateReceiver(); // Registers the DownloadStateReceiver and its intent filters LocalBroadcastManager.getInstance(this).registerReceiver( mDownloadStateReceiver, mStatusIntentFilter); ... BroadcastReceiver可以同时处理多种类型的Intent对象,这项特性可以为每种Action定义不同的代码,而不需要专门去定义BroadcastReceiver。为同一个BroadcastReceiver定义另外的IntentFilter,只需再创建一个IntentFilter,然后再次注册一下就好: /* * Instantiates a new action filter. * No data filter is needed. */ statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE); ... // Registers the receiver with the new filter LocalBroadcastManager.getInstance(getActivity()).registerReceiver( mDownloadStateReceiver, mIntentFilter); 发送广播Intent并不会启动或者恢复Activity。就算是APP处于挂起状态(处于后台)也同样会接收到Intent。如果APP处于挂起状态的话,有任务完成需要通知到用户,那么可以使用Notification做到。绝不要启动Activity来响应接收到的Intent广播。

优秀的个人博客,低调大师

首次对外公开,颁发官方证书,GOTC 2023 "实施和管理开源合规计划 "培训研讨会来啦!

开源软件已经成为现代软件开发的一个重要组成部分。它提供了许多好处,如成本效益、灵活性和社区支持。然而,使用开源软件也有责任遵守许可条款和条件。如果不遵守这些条款和条件,可能会导致法律和财务后果。 为了帮助企业驾驭这一复杂的局面,GOTC 大会与 LFOSSA(Linux Foundation开源软件学园)将举办"实施和管理开源合规计划"培训研讨会。本次研修班旨在帮助开发者、项目经理、法律顾问以及企业决策者更好地了解和应对开源软件合规相关的问题。通过对开源许可证、合规流程和最佳实践的深入剖析,希望参与者能够在此次研修班中掌握关键知识,以确保开源项目的合规性。 该研修班首次对外公开,共4 小时,研修班的导师是 Linux 基金会战略计划副总裁 Ibrahim Haddad 博士。学员完成培训后,LFOSSA 将为其颁发结业证书。持有GOTC门票人士可以到场参加研讨会。参加本研讨会的人士需要在场登记,名额有限,先到先得。 Ibrahim Haddad 博士是 Linux 基金会战略项目的副总裁和 LF AI & Data 基金会和PyTorch 基金会的执行董事。在他的职业生涯中,Ibrahim 曾在爱立信研究院、开源开发实验室、摩托罗拉、Palm、惠普、Linux 基金会和三星研究院担任技术和投资组合管理职务。他有非常多的著作和演讲,涉及的领域包括从法律合规到使用开源作为研发工具来推动合作和创新。 ImplementingandManaginganOpenSourceComplianceProgram 实施和管理开源合规计划 ByIbrahimHaddad 博士 VicePresident,StrategicPrograms TheLinuxFoundation 研讨会详情: 时间:5 月 28 日 13:30 -17:30 地点:上海张江科学会堂 5 层会议室 503-A 包含的关键议题: 1.开放源码合规性介绍 2.合规失败以及如何避免这些失败 3.企业开放源码合规性计划的概述 4.端对端合规管理 5. 合规计划:挑战和解决方案 6.详细的合规流程审查 7.合规团队 8.推荐做法 9.工具和自动化 10.扩展开源法律支持 11.管理开放源码合规性查询 这个研讨会将由在开源合规方面有丰富经验的 Ibrahim Haddad 博士主持。与会者将有机会提出问题,讨论他们具体的合规性挑战,并获得关于实施和管理有效的开源合规性计划的实用建议。通过参加这次研讨会,企业可以预期获得以下好处: 1. 减少法律和财务风险:通过实施一个有效的开源合规计划,企业可以减少与不合规相关的法律和财务后果的风险。 2. 提高效率:一个有效的开源合规计划可以帮助企业简化他们的开发流程,减少合规文件所需的时间和资源。 3. 提高声誉:对开放源码合规性的承诺可以提高一个组织在开放源码社区和潜在客户中的声誉。 4. 确保长期的可持续性:一个有效的开源合规计划可以帮助组织通过确保遵守许可条款和条件来确保其软件开发工作的长期可持续性。 总之,"实施和管理开源合规计划"培训研讨会将使与会者掌握必要的知识和工具,以制定有效的合规计划,减少法律和财务风险,并确保其软件开发工作的长期可持续性。今天就注册,以确保你的位置,并迈出走向卓越的开源合规的第一步。 持有 GOTC 门票人士可以到场参加研讨会。参加本研讨会的人士需要在场登记,名额有限,先到先得。 GOTC 2023 报名通道现即将关闭,诚邀全球各技术领域开源爱好者共襄盛举! 参会报名,请访问: https://www.bagevent.com/event/8387611 进入官网了解更多信息,请访问: https://gotc.oschina.net

优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:电池续航时间优化之按需开启广播接收器

原文地址:http://android.xsoftlab.net/training/monitoring-device-state/manifest-receivers.html 监测设备状态变化最简单的实现方式就是为每种状态都创建一个广播接收器,然后只需在相应的广播接收器内依据当前的设备状态重新执行各自的任务即可。 这种方式的不好之处就在于每次广播接收器被触发后,APP都会唤醒设备。 一种比较好的解决方案就是在运行时关闭或开启广播接收器。这样也可以使在清单文件中声明的广播接收器按需触发。 动态开启广播接收器 我们可以通过PackageManager将清单文件中声明过的任何组件切换到开启\关闭状态,其中也包括你将要开启或者关闭的广播接收器: ComponentName receiver = new ComponentName(context, myReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP) 通过使用这种方法,如果发现网络连接已经断开,那么就可以关闭所有的相关广播接收器,除了监听连接变化的广播接收器之外。反之,一旦连接到网络,那么则应当停止网络变化的监听:只需要在执行网络任务之前,检查一下是否有网络连接即可。 你也可以使用这种方式推迟那种需要超大带宽的网络任务。只需要监听一下网络连接的变化即可,一旦连接到Wi-Fi,那则可以开始进行网络下载。

优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:电池续航时间优化之检查、检测网络连接状态

原文地址:http://android.xsoftlab.net/training/monitoring-device-state/connectivity-monitoring.html 通常会有一些后台服务需要连接到网络来更新数据。但是如果没有连接到互联网,或者由于网络太慢而不能完成更新,那么为什么不在连接到网络后或在状况良好时再做这些工作呢? 你可以使用ConnectivityManager来检查是否已经连接到互联网,如果连接上了,还可以查询当前的网络连接类型。 检测是否联网 如果没有连接到网络,那么就没必要做基于网络的更新了。下面的代码演示了如何通过ConnectivityManager来检查当前的设备是否连接到了网络。 ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting(); 检测当前的网络连接类型 有时可能需要检查当前的网络连接类型。 移动设备的网络可能是蜂窝数据、WiMAX、Wi-Fi或以太网络提供。可以通过查询获知当前的网络连接类型,并基于当前的可用带宽来变更应用的刷新频率。 boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI; 移动数据所花费的成本要明显的高于Wi-Fi,所以在大多数情况下,当处于移动数据连接时,应当降低更新频率。类似的,较大文件的下载也应当暂停,直到连接到Wi-Fi网络后再继续下载。 因为会中断某些网络任务,所以监听网络状况变化这一点就变得尤为重要了:以便可以在良好的网络状况下恢复任务。 监听网络连接的变化 当网络状况发生变化时,ConnectivityManager会广播一个CONNECTIVITY_ACTION (“android.net.conn.CONNECTIVITY_CHANGE”)的消息。你可以在清单文件中注册一个专门用于监听此消息的广播接收器,以便恢复或暂停后台网络任务。 <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> 由于设备的网络连接会时常发生变化,所以该广播接收器会在每次切换到移动数据或者Wi-Fi情况下会被触发。因此,最好是为了恢复更新或者下载才用此种方法。通常的做法是,在开始任务之前检查一下网络的连接状况,如果网络不允许,那么使用该方法以便恢复。 这项方法需要动态开启广播接收器,具体的讲解会在下节课描述。

优秀的个人博客,低调大师

官方证实!Face++ 已完成新一轮 1 亿美元融资,来自建银国际和富士康

据彭博社消息,中国人工智能企业旷视 ( Face++ ) 刚刚完成了新一轮一亿美元的融资,投资者来自建银国际与富士康集团等等。 据不愿透露姓名的消息人士透露,旷视本次融资尚未完全结束,除了台湾鸿海集团(富士康)、建银国际,本轮还有其他投资人参与。目前本轮融资已经超过一亿美元。 旷视科技(Megvii)成立于 2011 年,总部位于北京,是国内一家专注于图像识别和深度学习的技术公司,外界常称之为“Face++”。三年前,构建在阿里云计算平台之上的 Face++人脸识别云平台正式上线。曾经惊艳了德国 CeBIT 的阿里“刷脸支付”——这项崭新的支付认证技术正是由蚂蚁金服与 Face++ 联手研发推出,旨在将“扫脸”代替传统的密码用于购物后的支付认证。 作为国内人脸识别领域知名的初创公司,旷视在创业之初就获得了联想之星的天使融资。2013 年

优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:电池续航时间优化之监测电池电量及充电状态

原文地址:http://android.xsoftlab.net/training/monitoring-device-state/index.html 引言 作为一款优秀的APP应用,应该总是想方设法的降低电量的消耗。通过这节课的学习,你将有能力使APP可以基于设备的状态来调整APP的功能及行为。 我们可以通过比如在断开连接时关闭后台服务,或者在电量低的时候降低更新的频率等等手段来降低电量的消耗。 监测电池电量及充电状态 在更改后台的更新频次时,检查当前的电池电量及充电状态是我们先要做的。 应用程序的更新频率取决于电池的电量以及充电状态。由于设备处于充电状态时应用的耗电量几乎可以忽略,所以,在设备连接到充电器时,你可以将应用的刷新频率开到最大,如果设备没有在充电,那么降低更新频率可以延长电池的使命时间。 检查当前的充电状态 首先我们需要检查当前的充电状态。BatteryManager会将电池信息以及充电信息通过粘性Intent将其广播。 因为是粘性Intent,所以不需要注册BroadcastReceiver,只需要在调用registerReceiver()时传一个null就可以,当前的电池状态由该方法直接返回。你也可以在这里传递一个BroadcastReceiver对象,但是我们接下来的处理方式并不是在其中做的,所以这并不是必须的。 IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); Intent batteryStatus = context.registerReceiver(null, ifilter); 如果设备当前处于充电状态,那么可以获得当前的充电状态,无论它是通过USB还是通过AC适配器充电的。 // Are we charging / charged? int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL; // How are we charging? int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; 通常的做法是:应当是在连接到AC电源适配器时,将后台的更新频率加到最大,如果当前处于USB状态,这个频率应当适当降低,如果断开充电,则应当进一步降低。 监测充电状态的变化 设备的充电状态很容易随着充电器的插入、拔出而发生变化。所以随着充电状态的变化应当相应的调整应用的刷新频率。 当设备插上充电器或是拔出充电器时,BatteryManager都会广播一个Action,所以应当注册一个BroadcastReceiver用来监听这些事件。在清单文件中需要定义ACTION_POWER_CONNECTED及ACTION_POWER_DISCONNECTED的意图过滤器。 <receiver android:name=".PowerConnectionReceiver"> <intent-filter> <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/> <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/> </intent-filter> </receiver> 在该BroadcastReceiver内,你可以获取当前的充电状态: public class PowerConnectionReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL; int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; } } 检查电池的剩余电量 在一些情况下还需要检查设备的剩余电量。当电量较低时可能需要降低应用的后台服务频率。 你可以通过以下方式获得设备的剩余电量: int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1); float batteryPct = level / (float)scale; 监测电量的重要变化 应用不能一直连续不断的监听电池的状态。 通常来说,一直不断的监听电池电量会使监听电池的任务大于应用的实际任务,所以最好是只监听一些比较重要的变更事件。 下面的清单文件摘自一段广播接收器内。该广播接收器会在电池的电量很低时或者是在电量恢复到安全水平时被触发。它监听了两个事件:ACTION_BATTERY_LOW及ACTION_BATTERY_OKAY. <receiver android:name=".BatteryLevelReceiver"> <intent-filter> <action android:name="android.intent.action.ACTION_BATTERY_LOW"/> <action android:name="android.intent.action.ACTION_BATTERY_OKAY"/> </intent-filter> </receiver> 通常情况下,在电量很低时要关闭所有的后台更新。加载在使用APP之前,手机关机了,那么应用的数据是否是最新的就没那么重要了。 在很多情况下,手机充电时是被放在一个固定的位置上的。下节课我们将会学习如何检查设备的放置环境以及如何监测设备的放置状态。

优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:键盘输入处理之控制输入法的显示方式

原文地址:http://android.xsoftlab.net/training/keyboard-input/visibility.html 当输入的焦点进入或者离开文本框时,Android会适时的显示或隐藏输入法。系统还会决定UI及文本框如何出现在输入法的上方。比如,当垂直方向上的可用空间非常紧张时,那么文本框可能就会填充输入法上方的整个区域。对于大多数的APP来说,这样的默认行为是它们所需要的。 不过在另一些情况中,你可能需要直接控制输入法的显示方式,以及需要在输入法可见的时候控制UI的排布方式。那么这节课主要就是介绍如何实现这些。 在Activity启动的时候显示输入法 尽管在Activity启动的时候Android将焦点给了第一个文本框,但是它是不会触发输入法弹出的。这样的行为是符合正常的习惯的,因为进入文本框可能不会Activity启动后的首要任务。不管怎么说,如果进入文本框是Activity的首要任务的话(比如登录界面),那么你可能希望默认情况下进入Activity后就会弹出输入法。 为了在Activity启动后可以显示输入法,需要在清单文件中对应的Activity的元素中添加属性android:windowSoftInputMode。如下: <application ... > <activity android:windowSoftInputMode="stateVisible" ... > ... </activity> ... </application> Note:如果用户的设备含有实体按键,那么软键盘是不会弹出的。 按需求弹出输入法 如果在Activity的生命周期内有这么一个方法:你希望确保在该方法调用后输入法是可见的,那么你可以使用InputMethodManager来将它弹出。 举个例子,下面的方法持有了一个View对象,用户会在这个View内部输入点什么,所以调用requestFocus()方法可以将焦点赋给它,然后showSoftInput()就会将输入法打开: public void showSoftKeyboard(View view) { if (view.requestFocus()) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); } } Note: 一旦输入法被弹出,那么最好不要使用代码隐藏它。系统会在用户终止文本框中的任务后将它隐藏或者用户通过系统隐藏了它(比如使用了返回按钮)。 指明你的UI应该如何响应输入法的弹出 当输入法出现在屏幕上时,它会减少APP在屏幕上的使用空间。那么系统会决定如何调整UI的部分区域,但是它可能不是最准确的。为了确保APP拥有最佳的用户体验,应该指明系统如何调整UI。 为了声明Activity的首选方式,应当在项目的清单文件中对应的Activity下添加android:windowSoftInputMode属性,并使用其中一个含有”adjust”的值。 举个例子,为了确保系统可将UI调整到可用区域,应当使用”adjustResize”: <application ... > <activity android:windowSoftInputMode="adjustResize" ... > ... </activity> ... </application> 除了以上的方法,你还可以使用组合的的方式来声明UI调整规则与输入法的可见性规则: <activity android:windowSoftInputMode="stateVisible|adjustResize" ... > ... </activity> 指明”adjustResize”是很重要的:如果UI中含有一些用户可能需要迅速访问的按键或者需要操作的文本框的话。举个例子,如果你使用相对布局将一个按钮放置到了屏幕的底部,那么使用”adjustResize”调整布局可以使该按钮出现在输入法的顶部,这样在输入完成之后就可以直接点击该按钮。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册