当前位置: 首页 > wzjs >正文

百度的推广广告长沙百度快速优化排名

百度的推广广告,长沙百度快速优化排名,网站直播的功能怎样做,如何网上外贸接单功能背景 APN 数据通常存储在数据库中,由TelephonyProvider提供。当用户进入APN设置界面时,Activity会启动,AOSP源码通过ContentResolver查询APN数据。关键分析点在于这个查询操作是否在主线程执行,因为主线程上的耗时操作会导致…

功能背景

APN 数据通常存储在数据库中,由TelephonyProvider提供。当用户进入APN设置界面时,Activity会启动,AOSP源码通过ContentResolver查询APN数据。关键分析点在于这个查询操作是否在主线程执行,因为主线程上的耗时操作会导致ANR。

技术演进补充

自Android 9(API 28)起,系统对Telephony.Carriers表的访问增加了权限限制:

  • 需要Carrier PrivilegesWRITE_APN_SETTINGS权限
  • 查询结果可能返回空Cursor,需配合SubscriptionManager处理多SIM卡场景

分析

通常,Android的ContentProvider处理数据请求,而TelephonyProvider继承自ContentProvider。查询操作可能会在后台线程执行,但需要确认。例如,CursorLoader会在后台线程处理查询,但如果是直接使用ContentResolver.query,可能就在主线程了。

Android源码中

  • 使用LoaderManager来异步加载数据,这样查询会在后台进行。
  • 如果用户使用的是直接查询而没有异步处理,那么主线程可能被阻塞。

排查建议

检查ApnSettingsActivity的onCreate或onResume方法,看是否触发数据加载。

  • 使用LoaderManager.initLoader来启动CursorLoader,这样查询会在后台线程执行。
  • 否则,如果直接在主线程调用getContentResolver().query,就会在主线程执行数据库操作。

疑问

Q:getContentResolver().query都是在主线程执行的吗?

A:直接调用getContentResolver().query取决于调用线程。

根据Android文档,ContentResolver的query方法默认是在调用线程执行的。如果直接在主线程调用getContentResolver().query,那么查询会在主线程执行,可能导致UI卡顿甚至ANR。然而,当使用CursorLoader时,内部会使用AsyncTask或者类似的机制,在后台线程执行查询,从而避免主线程阻塞。

CursorLoader内部封装了异步查询,所以即使调用了ContentResolver的query方法,也是在Loader管理的后台线程中执行的,而不是主线程。

正确使用Loader或现代的替代方案(如Room的LiveData + ViewModel)来确保数据库操作不在主线程进行。

关键结论

  1. 直接调用:若在Activity/Fragment主线程中直接调用getContentResolver().query()确实会在主线程执行数据库操作,可能导致ANR
  2. 通过Loader机制:当使用CursorLoader时,系统自动在后台线程执行查询,通过Handler将结果回调到主线程
线程行为对比表
调用方式执行线程是否阻塞UI推荐场景
直接调用query()调用线程可能阻塞小型数据集/非UI线程调用
CursorLoader自动执行queryAsyncTask线程池无阻塞列表数据加载等标准场景

 

对疑问的代码执行流程验证

原生CursorLoader实现原理(简化版):

// Framework简化的Loader线程切换逻辑
public class CursorLoader extends AsyncTaskLoader<Cursor> {@Overridepublic Cursor loadInBackground() { // 在AsyncTask线程执行return getContext().getContentResolver().query(uri, ...);}@Overrideprotected void onStartLoading() {forceLoad(); // 触发异步加载}
}

 主线程验证代码:

// 验证调用线程的测试代码
new Handler(Looper.getMainLooper()).post(() -> {// 在主线程执行查询Cursor cursor = getContentResolver().query(Carriers.CONTENT_URI, ...);Log.d("ThreadTest", "MainThread query: " + (Looper.myLooper() == Looper.getMainLooper()));
});// 输出结果:ThreadTest: MainThread query: true

代码实现

优化设想

用户打开界面,Activity初始化Loader,LoaderManager启动CursorLoader,CursorLoader在后台线程执行查询,通过ContentResolver调用TelephonyProvider的query方法,最终获取APN数据并返回给主线程更新UI

APN Settings界面数据加载时序图(优化)
APN Settings界面数据优化加载时序图

 

%% APN Settings界面数据加载时序图
sequenceDiagramparticipant Userparticipant ApnSettingsActivityparticipant LoaderManagerparticipant CursorLoaderparticipant TelephonyProviderparticipant DatabaseUser->>ApnSettingsActivity: 启动APN设置界面activate ApnSettingsActivityApnSettingsActivity->>LoaderManager: initLoader(APN_LOADER_ID)LoaderManager->>CursorLoader: 创建新Loader实例activate CursorLoaderCursorLoader->>TelephonyProvider: 异步执行query()activate TelephonyProviderTelephonyProvider->>Database: 执行SQL查询activate DatabaseDatabase-->>TelephonyProvider: 返回APN数据Cursordeactivate DatabaseTelephonyProvider-->>CursorLoader: 返回查询结果deactivate TelephonyProviderCursorLoader-->>LoaderManager: 交付结果deactivate CursorLoaderLoaderManager->>ApnSettingsActivity: onLoadFinished()ApnSettingsActivity->>ApnSettingsActivity: 更新UI列表deactivate ApnSettingsActivityNote right of CursorLoader: 关键路径说明<br/>1. CursorLoader自动处理后台线程<br/>2. 数据库查询在AsyncTask线程池执行<br/>3. 结果通过Handler返回主线程

如下是优化方案的案例,但是原生逻辑并不是直接一个Activity

package com.android.settings.network.apn;// APN数据库查询不会阻塞主线程,通过CursorLoader机制实现
// 实际查询发生在AsyncTask线程(AsyncTask.THREAD_POOL_EXECUTOR)
// 结果回调通过Handler机制返回主线程// ApnSettings.java 核心逻辑
public class ApnSettings extends PreferenceActivity implements LoaderManager.LoaderCallbacks<Cursor> {@Overrideprotected void onCreate(Bundle savedInstanceState) {getLoaderManager().initLoader(APN_LOADER_ID, null, this); // 启动异步加载}@Overridepublic Loader<Cursor> onCreateLoader(int id, Bundle args) {return new CursorLoader(this, Telephony.Carriers.CONTENT_URI,PROJECTION, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);}@Overridepublic void onLoadFinished(Loader<Cursor> loader, Cursor data) {mAdapter.swapCursor(data); // 主线程更新UI}
}

以上符合Android的最佳实践,即避免在主线程进行IO操作。

  • ApnSettingsActivity使用了LoaderManager来初始化CursorLoader。
  • 在onCreateLoader方法中创建了CursorLoader实例,参数包括ContentProvider的URI和查询参数。
  • 当LoaderManager启动加载时,CursorLoader会在后台线程执行查询,完成后再通过onLoadFinished回调主线程更新UI。

 AOSP

packages/apps/Settings/src/com/android/settings/network/apn/ApnSettings.java

/** Handle each different apn setting. */
public class ApnSettings extends RestrictedSettingsFragmentimplements Preference.OnPreferenceChangeListener {static final String TAG = "ApnSettings";

    http://www.dtcms.com/wzjs/305827.html

    相关文章:

  1. 如果做淘宝网站项目推广
  2. 海口网站建设流程搜多多搜索引擎入口
  3. 做网站的人会不会拿走我的网站如何查询网站收录情况
  4. 学生处网站建设招标公告杭州网站优化咨询
  5. 做原型的素材网站搜索引擎优化技术有哪些
  6. 天河区建网站免费自助建站哪个最好
  7. 室内设计应该学什么专业六盘水seo
  8. 昌吉建设网站网上营销是做什么的
  9. 网店网站建设天津做优化好的公司
  10. 建站公司banner游戏代理
  11. 98元建网站创建网站的流程
  12. 山西自助建站费用低懂得网站推广
  13. wordpress个人展示网站百度空间登录
  14. 惠州做棋牌网站建设哪家好男生短期培训就业
  15. 长沙网站建设价格百度推广价格价目表
  16. 360网站备案谷歌google下载安卓版 app
  17. 成都市双流区建设局官方网站汽油价格最新调整最新消息
  18. 济南网站建设vashine百度超级链
  19. 做网站的内容黄冈网站推广优化找哪家
  20. 南部县人民医院招聘信息关键词优化哪家强
  21. 福永镇网站建设互动网站建设
  22. 网站建设预算策划怎样在百度上注册自己的店铺
  23. javascript代码大全优化师是做什么的
  24. 网站建设设计计划表怎么查询搜索关键词
  25. 网站建设的企业友情链接交换教程
  26. 库尔勒网站南宁百度推广代理商
  27. 俄罗斯做电商网站品牌推广内容
  28. 百度云网站开发怎样开网站友情链接检查
  29. 短租网站那家做的好平台优化是指什么
  30. 男女做暖暖插孔网站上线了建站