- 浏览: 1056013 次
- 性别:
- 来自: 南昌
文章分类
- 全部博客 (276)
- 生活 (1)
- 代码之美 (22)
- Media (7)
- Android Widget (3)
- Android Intent (1)
- Android Activity (4)
- UI event handle--UI事件处理机制 (2)
- Java基础知识 (12)
- android Databases (5)
- Android 系统知识 (70)
- 平常遇到的问题与解决方法 (38)
- Android TextView/EditView (2)
- Thinking Java (1)
- android webkit (6)
- JSON (1)
- XML (4)
- HTTP (1)
- Google Weather API (1)
- android 2.3 NFC (10)
- android app (20)
- android framework (7)
- C++ (2)
- android System (5)
- Pthread (1)
- Wifi (8)
- Unix/Linux C (8)
- Android 4.0 (1)
- Mail (1)
- Smack 源码学习 (4)
- iOS (4)
- Android (1)
- git (1)
- Gallery3d (2)
- React-Natice (1)
最新评论
-
dd18349182956:
你是用的smack哪个版本?我用的smack4.1.3和sma ...
关于socket长连接的心跳包 -
xukaiyin:
全英文
getApplicationContext()与this,getBaseContext() -
裂风矢:
...
<category android:name="android.intent.category.DEFAULT" /> 惹的祸 -
xanthodont:
mark一下
XMPP——Smack -
Evilover3:
mark一下,学习了
XMPP——Smack
当用户在Setting中清除了Email的data,再返回到Email进行新建邮件就会一直显示“waiting for sync”.从字面的意思就是要进行同步,我跑到Setting-->Account中手动同步了账号,再新建邮件,发现问题仍一直存在。
1.导出Email APP的数据查看Account tables的数据发现,发生问题和正常时数据是一致的
2.通过搜索“waiting for sync”定位到显示该UI的是在ComposeActivity.java中
3.接着分析何时会调用showWaitFragment,发现是当Account的状态处于
INITIAL_SYNC_NEEDED或者ACCOUNT_INITIALIZATION_REQUIRED
4.接着分析syncStatus的值的来源
通过加log打印发现account最后SYNC_STATUS都会修改为NO_SYNC,为何在ComposeActivity查询出来的仍旧是INITIAL_SYNC_NEEDED
5.返回ComposeActivity分析Account的加载过程
首先是checkValidAccounts中
调用AccountUtils.getAccounts查询出Account
此处调用查询的uri是content://com.android.mail.accountcache/它对应的ContentProvider是UnifiedAccountCacheProvider,真正实现的是MailAppProvider
6.分析发现MailAppProvider会将从EmailProvider查询到结果缓存到SharePreference和mAccountCache中,当query只是从mAccountCache获取,而MailAppProvider会在onCreate的时候就会从EmailProvider中获取结果,并且此时account并没有同步完成导致缓存的结果的syncstatus是INITIAL_SYNC_NEEDED
7.那问题点找到了,该如何解决呢?如何让ComposeActivity获取到最新的状态。又返回到了checkValidAccounts中,发现当isAccountReady 返回false时,会重新getLoaderManager().initLoader(LOADER_ACCOUNT_CURSOR, null, this);说明会进行二次查询,可是此处查询的仍然是MailAppProvider缓存的结果,而非EmailProvider中的
从上面的code可以看到uri和projection与AccountUtils.getAccounts一样,所以数据当然一样啊,仍然是INITIAL_SYNC_NEEDED。
8.那居然google原本就设计了第二次查询,那最简单的解决方法就是在二次查询的时候将uri指向EmailProvider这样,问题就解决了。
此处指向的uri为content://com.android.email.provider/uiaccts
9.测试,问题解决。Google也有出错的时候,只要是人写的code就会有漏洞!
1.导出Email APP的数据查看Account tables的数据发现,发生问题和正常时数据是一致的
2.通过搜索“waiting for sync”定位到显示该UI的是在ComposeActivity.java中
private void showWaitFragment(Account account) { WaitFragment fragment = getWaitFragment(); if (fragment != null) { fragment.updateAccount(account); } else { findViewById(R.id.wait).setVisibility(View.VISIBLE); replaceFragment(WaitFragment.newInstance(account, false /* expectingMessages */), FragmentTransaction.TRANSIT_FRAGMENT_OPEN, TAG_WAIT); } }
3.接着分析何时会调用showWaitFragment,发现是当Account的状态处于
INITIAL_SYNC_NEEDED或者ACCOUNT_INITIALIZATION_REQUIRED
public boolean isAccountReady() { return !isAccountInitializationRequired() && !isAccountSyncRequired(); } public boolean isAccountSyncRequired() { return (syncStatus & SyncStatus.INITIAL_SYNC_NEEDED) == SyncStatus.INITIAL_SYNC_NEEDED; } public boolean isAccountInitializationRequired() { return (syncStatus & SyncStatus.ACCOUNT_INITIALIZATION_REQUIRED) == SyncStatus.ACCOUNT_INITIALIZATION_REQUIRED; }
4.接着分析syncStatus的值的来源
private String genQueryAccount(String[] uiProjection, String id) { .... if (projectionColumns.contains(UIProvider.AccountColumns.SYNC_STATUS)) { if (inboxMailboxId != Mailbox.NO_MAILBOX) { values.put(UIProvider.AccountColumns.SYNC_STATUS, UIProvider.SyncStatus.NO_SYNC); } else { values.put(UIProvider.AccountColumns.SYNC_STATUS, UIProvider.SyncStatus.INITIAL_SYNC_NEEDED); } } ...
通过加log打印发现account最后SYNC_STATUS都会修改为NO_SYNC,为何在ComposeActivity查询出来的仍旧是INITIAL_SYNC_NEEDED
5.返回ComposeActivity分析Account的加载过程
首先是checkValidAccounts中
private void checkValidAccounts() { final Account[] allAccounts = AccountUtils.getAccounts(this); if (allAccounts == null || allAccounts.length == 0) { final Intent noAccountIntent = MailAppProvider.getNoAccountIntent(this); if (noAccountIntent != null) { mAccounts = null; startActivityForResult(noAccountIntent, RESULT_CREATE_ACCOUNT); } } else { // If none of the accounts are syncing, setup a watcher. boolean anySyncing = false; for (Account a : allAccounts) { if (a.isAccountReady()) { anySyncing = true; break; } } if (!anySyncing) { // There are accounts, but none are sync'd, which is just like having no accounts. mAccounts = null; getLoaderManager().initLoader(LOADER_ACCOUNT_CURSOR, null, this); return; } mAccounts = AccountUtils.getSyncingAccounts(this); finishCreate(); } }
调用AccountUtils.getAccounts查询出Account
public static Account[] getAccounts(Context context) { final ContentResolver resolver = context.getContentResolver(); Cursor accountsCursor = null; final List<Account> accounts = Lists.newArrayList(); try { accountsCursor = resolver.query(MailAppProvider.getAccountsUri(), UIProvider.ACCOUNTS_PROJECTION, null, null, null); if (accountsCursor != null) { while (accountsCursor.moveToNext()) { accounts.add(Account.builder().buildFrom(accountsCursor)); } } } finally { if (accountsCursor != null) { accountsCursor.close(); } } return accounts.toArray(new Account[accounts.size()]); } }
此处调用查询的uri是content://com.android.mail.accountcache/它对应的ContentProvider是UnifiedAccountCacheProvider,真正实现的是MailAppProvider
6.分析发现MailAppProvider会将从EmailProvider查询到结果缓存到SharePreference和mAccountCache中,当query只是从mAccountCache获取,而MailAppProvider会在onCreate的时候就会从EmailProvider中获取结果,并且此时account并没有同步完成导致缓存的结果的syncstatus是INITIAL_SYNC_NEEDED
7.那问题点找到了,该如何解决呢?如何让ComposeActivity获取到最新的状态。又返回到了checkValidAccounts中,发现当isAccountReady 返回false时,会重新getLoaderManager().initLoader(LOADER_ACCOUNT_CURSOR, null, this);说明会进行二次查询,可是此处查询的仍然是MailAppProvider缓存的结果,而非EmailProvider中的
@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { switch (id) { case INIT_DRAFT_USING_REFERENCE_MESSAGE: return new CursorLoader(this, mRefMessageUri, UIProvider.MESSAGE_PROJECTION, null, null, null); case REFERENCE_MESSAGE_LOADER: return new CursorLoader(this, mRefMessageUri, UIProvider.MESSAGE_PROJECTION, null, null, null); case LOADER_ACCOUNT_CURSOR: return new CursorLoader(this, MailAppProvider.getAccountsUri(), UIProvider.ACCOUNTS_PROJECTION, null, null, null); } return null; }
从上面的code可以看到uri和projection与AccountUtils.getAccounts一样,所以数据当然一样啊,仍然是INITIAL_SYNC_NEEDED。
8.那居然google原本就设计了第二次查询,那最简单的解决方法就是在二次查询的时候将uri指向EmailProvider这样,问题就解决了。
@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { switch (id) { case INIT_DRAFT_USING_REFERENCE_MESSAGE: return new CursorLoader(this, mRefMessageUri, UIProvider.MESSAGE_PROJECTION, null, null, null); case REFERENCE_MESSAGE_LOADER: return new CursorLoader(this, mRefMessageUri, UIProvider.MESSAGE_PROJECTION, null, null, null); case LOADER_ACCOUNT_CURSOR: final String[] accountQueryUris = this.getResources().getStringArray(R.array.account_providers); return new CursorLoader(this, Uri.parse(accountQueryUris[0]), UIProvider.ACCOUNTS_PROJECTION, null, null, null); } return null; }
此处指向的uri为content://com.android.email.provider/uiaccts
9.测试,问题解决。Google也有出错的时候,只要是人写的code就会有漏洞!
发表评论
-
Android Webview加载www.youtube.com的问题
2019-04-25 10:36 955Android Webview加载www.youtube.co ... -
EditText键盘删除字符的原理
2018-10-29 19:21 1197转https://blog.csdn.net/tankai19 ... -
Background execution not allowed
2018-10-22 19:02 327311-05 10:08:18.058 673 736 ... -
failed to set system property
2018-10-17 09:21 4165在App的mk文件设置了LOCAL_CERTIFICATE : ... -
CtsDeqpTestCases fail
2018-07-27 09:44 2908Suite / Plan:VTS / cts-on-gsi ... -
在DocumentUI中的Recent(最近)列表无法显示图片的缩略图
2018-06-12 18:23 906今天客户提了一个bug说在短信添加附件,界面无法显示缩略图。接 ... -
在任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态,且音乐仍在后台播放
2018-06-05 11:28 1548在任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态,且音乐 ... -
junit.framework.AssertionFailedError: Failed to get achievable frame rates for O
2018-05-25 15:41 2252之前对于CTS测试的失败case接触不多,组长突然转了这样一个 ... -
Android 模拟各种事件的方法
2018-05-17 16:30 1488有时候没有对应的硬件设备,那我们就得通过某种方式来模拟。比如模 ... -
javax.net.ssl.SSLHandshakeException: Unacceptable certificate: CN=GeoTrust SSL C
2018-01-30 16:48 3638最近从Android N升级到Android O,发现163的 ... -
Email中附件名称中包含中文字符显示乱码
2017-11-28 17:09 1574Email中附件名称中包含中文字符显示乱码是因为附件虽包含了中 ... -
不能再通过createPackageContext来访问另外一个应用的资源(Sharepreference)
2017-11-14 17:22 1432以前我们可以通过createPackageContext来访问 ... -
当Email未设置账户时,通过ACTION_SENDTO启动会报ActivityNotFoundException
2017-09-27 18:15 505当Email未设置账户时,通过ACTION_SENDTO启动会 ... -
java.lang.SecurityException: Permission Denial: reading...requires android.permi
2016-05-12 11:12 2299一直在忙于Gallery,最近遇到了这样的bug,在Setti ... -
android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a read
2015-11-27 14:50 2910android.database.sqlite.SQLiteR ... -
AsyncTask
2015-08-21 17:43 383转自http://blog.csdn.net/hitlion2 ... -
解决IllegalStateException: Can not perform this action after onSaveInstanceState
2015-08-07 18:07 1047转自http://www.cnblogs.com/zgz345 ... -
Android setTag方法的key问题
2015-08-03 19:22 1031转自http://www.cnblogs.com/whitew ... -
ActivityGroup对子Activity的管理
2013-06-27 17:41 2070转自http://eyeandroid.diandian.co ... -
listview在activitygroup切换后无法点击的问题
2013-05-14 10:14 1466转自:http://blog.csdn.net/daguaio ...
相关推荐
前端项目-bootstrap-waitingfor,Waiting for dialog with progress bar for Bootstrap
MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景。而且,一旦alter table TableA的操作停滞在Waiting for table metadata lock的状态,后续对TableA的任何操作(包括读)...
与npm 您可以使用npm npm install --save bootstrap-waitingfor安装此模块,并如下所示包含它: const waitingDialog = require ( 'bootstrap-waitingfor' ) ;使用在您JavaScript代码中,编写如下内容: ...
解决Another app is currently holding the yum lock; waiting for it to exit.
ZeroTier One,1.6.2版本,内网穿透,微软,WINDOWS,MSI安装程序(x86 / x64)
Vscode连接服务器时一直卡在Waiting for Downloading VS Code Server,需要手动下载的文件。放到~/.vscode-server/bin目录下 vscode-server-linux-x64.tar.gz
android studio 4.1.2 直接安装到 win7 64位会出现无法编译,提示缺少“c runtime lib”等问题。编译成功后会出现“HAXM device is not found”的问题。本文根据安装遇到的问题整理了相关问题的解决方法。在自己的...
Get started in creating marketable apps for the burgeoning Android market. Begin your journey by learning the essentials of programming for phones and tables that are built around Google’s wildly-...
Get started in creating marketable apps for the burgeoning Android market. Begin your journey by learning the essentials of programming for phones and tables that are built around Google's wildly-...
waiting-for-the-bus-server提供了一些查询机构、路线、站点和时间的方法。 它还具有空间查询功能,可以查找附近的站点、路线和机构。 有一个为 Pebble Smartwatch 开发的应用程序使用该服务器提供的 API。 你可以...
We're doing it like everyone does: sending an e-mail to the user, and waiting for the user to click a link. The only validation we do is to check the e-mail with usual regex... but we need to go a ...
广东省博罗县泰美中学七年级英语上册 Module 9 Unit 2 They’re waiting for buses or trains导学案(无答案)(新版)外研版
about to fork child process, waiting until server is ready for connections. forked process: 3560 ERROR: child process failed, exited with error number 1 To see additional information in this output, ...
MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景。而且,一旦alter table TableA的操作停滞在Waiting for table metadata lock的状态,后续对TableA的任何操作(包括读)...
NULL 博文链接:https://zhangyou1010.iteye.com/blog/1436632
android4.0 sms源码, 很多新特性, 可以参考啊。 老乔年轻时说, 有名的艺术家是抄袭, 伟大的艺术家是偷窃。 what are you waiting for ? let's do it !
自制鼠标指针- waiting (仅一个图标 waiting 忙)
right here waiting 的简谱 图片
Android系统编译过程中常见问题汇总