- 浏览: 1065642 次
- 性别:
- 来自: 南昌
文章分类
- 全部博客 (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 989Android Webview加载www.youtube.co ... -
EditText键盘删除字符的原理
2018-10-29 19:21 1244转https://blog.csdn.net/tankai19 ... -
Background execution not allowed
2018-10-22 19:02 357111-05 10:08:18.058 673 736 ... -
failed to set system property
2018-10-17 09:21 4357在App的mk文件设置了LOCAL_CERTIFICATE : ... -
CtsDeqpTestCases fail
2018-07-27 09:44 3010Suite / Plan:VTS / cts-on-gsi ... -
在DocumentUI中的Recent(最近)列表无法显示图片的缩略图
2018-06-12 18:23 938今天客户提了一个bug说在短信添加附件,界面无法显示缩略图。接 ... -
在任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态,且音乐仍在后台播放
2018-06-05 11:28 1630在任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态,且音乐 ... -
junit.framework.AssertionFailedError: Failed to get achievable frame rates for O
2018-05-25 15:41 2341之前对于CTS测试的失败case接触不多,组长突然转了这样一个 ... -
Android 模拟各种事件的方法
2018-05-17 16:30 1520有时候没有对应的硬件设备,那我们就得通过某种方式来模拟。比如模 ... -
javax.net.ssl.SSLHandshakeException: Unacceptable certificate: CN=GeoTrust SSL C
2018-01-30 16:48 3768最近从Android N升级到Android O,发现163的 ... -
Email中附件名称中包含中文字符显示乱码
2017-11-28 17:09 1609Email中附件名称中包含中文字符显示乱码是因为附件虽包含了中 ... -
不能再通过createPackageContext来访问另外一个应用的资源(Sharepreference)
2017-11-14 17:22 1462以前我们可以通过createPackageContext来访问 ... -
当Email未设置账户时,通过ACTION_SENDTO启动会报ActivityNotFoundException
2017-09-27 18:15 533当Email未设置账户时,通过ACTION_SENDTO启动会 ... -
java.lang.SecurityException: Permission Denial: reading...requires android.permi
2016-05-12 11:12 2363一直在忙于Gallery,最近遇到了这样的bug,在Setti ... -
android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a read
2015-11-27 14:50 2954android.database.sqlite.SQLiteR ... -
AsyncTask
2015-08-21 17:43 413转自http://blog.csdn.net/hitlion2 ... -
解决IllegalStateException: Can not perform this action after onSaveInstanceState
2015-08-07 18:07 1089转自http://www.cnblogs.com/zgz345 ... -
Android setTag方法的key问题
2015-08-03 19:22 1072转自http://www.cnblogs.com/whitew ... -
ActivityGroup对子Activity的管理
2013-06-27 17:41 2102转自http://eyeandroid.diandian.co ... -
listview在activitygroup切换后无法点击的问题
2013-05-14 10:14 1494转自:http://blog.csdn.net/daguaio ...
相关推荐
前端开发者常常需要在用户进行某些耗时操作(如数据加载、提交表单等)时显示反馈,以告知用户系统正在处理请求。"前端项目-bootstrap-waitingfor"就是这样一个解决方案,它提供了一个等待对话框,并结合了进度条...
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代码中,编写如下内容: ...
在Android应用开发过程中,开发者经常会遇到“Failed to install .apk on device 'emulator-5554': timeout”这样的错误,这通常是由于安装APK到设备(通常是Android模拟器)时超时导致的。这个错误可能会影响开发...
waiting for it to exit" 是一个常见的错误信息,意味着当前有另一个应用程序正在占用yum的锁,阻止了你执行新的yum操作。当你试图运行yum命令(如安装、更新或删除软件包)时,可能会遇到这个问题。下面我们将深入...
在使用Android Studio 4.1.2开发环境时,针对Win7 64位操作系统,可能会遇到一些安装和运行上的问题。本文将详细介绍如何解决这些问题,确保Android Studio能顺利运行。 首先,对于“c runtime lib”缺失的问题,这...
ZeroTier One,1.6.2版本,内网穿透,微软,WINDOWS,MSI安装程序(x86 / x64)
标题中的“上传文件时,线程一直waiting”指的是在进行文件上传操作时,程序中的某个线程进入等待状态,这通常涉及到多线程编程和并发控制。这种情况可能由多种原因引起,例如同步机制不当、资源竞争、死锁或阻塞等...
AndroidStudio使用过程中出现的异常 异常信息: Gradle sync failed: Unable to start the daemon process. This problem might be caused by incorrect configuration of the daemon. For example, an ...
Timeout Waiting for DHCP(解决方案).md
timed out waiting for connection to ZooKeeper解决方案(亲测可用)
waiting-for-the-bus-server提供了一些查询机构、路线、站点和时间的方法。 它还具有空间查询功能,可以查找附近的站点、路线和机构。 有一个为 Pebble Smartwatch 开发的应用程序使用该服务器提供的 API。 你可以...
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, ...
"Android动态点点省略号闪烁效果的等待控件"是一种常见的设计,它通过连续显示“...”来表示程序正在进行后台操作,同时通过动态闪烁增加用户的交互感,提高用户体验。本篇将详细介绍如何实现这样的控件。 首先,...
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 ...
Vscode连接服务器时一直卡在Waiting for Downloading VS Code Server,需要手动下载的文件。放到~/.vscode-server/bin目录下 vscode-server-linux-x64.tar.gz
众所周知,当我们通过ssh远程登录到另一台服务器之后,如果长时间不做操作,那么会被服务器自动登出,并且会告诉你timed out waiting for input: auto-logout。如果不通过tmux这些辅助工具来维持session的话,那么...