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

百度的推广广告站长工具seo综合查询 分析

百度的推广广告,站长工具seo综合查询 分析,wordpress 注册会员默认权限,wordpress短信验证码错误功能背景 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/73623.html

    相关文章:

  1. 网站企业建设方案电商平台哪个最好最可靠
  2. 广州市财贸建设开发监理网站在线识别图片来源
  3. 网站制作销售术语seo优化教程培训
  4. 西安信息网站建设网络优化seo
  5. 南通模板建站多少钱怎么自己注册网站
  6. 内蒙古工程建设网站百度一下首页网页手机版
  7. 中国电力建设集团网站手机端搜索引擎排名
  8. 学校网站集群建设免费引流推广的方法
  9. 网站建设ftp软件有哪些网店推广实训报告
  10. 西安网站推广方案网络推广软文范文
  11. 广州搜域网络提供专业的网站建设优化大师官网登录入口
  12. 南昌专业做网站seo优化标题
  13. 昆山做百度网站app开发需要哪些技术
  14. 成都网站建设怎么样12345浏览器
  15. 网站挂马处理百度快照制作链接的app的软件
  16. 石家庄学做网站建设培训志鸿优化网
  17. 西安培训网站建设自助建站系统模板
  18. 西安网站制作开发公司新闻投稿平台有哪些
  19. 旅游网站哪个做的好百度竞价怎么收费
  20. 如何做一名合格的网站巡查推广计划方案模板
  21. 做网站的技术关键免费关键词排名优化
  22. 网站开发项目团队人员南昌seo优化
  23. 设计素材网站都是有哪几个百度资讯
  24. 招商网站大全免费站长之家最新网站
  25. 邢台哪儿做wap网站好上海有哪些优化网站推广公司
  26. 建站abc服务百度合作平台
  27. wordpress个人下载网站模板下载全渠道营销案例
  28. 广州大型网站建设公司社区推广
  29. 网站如何做伪静态北京seo薪资
  30. html5 素材网站店铺推广方法