ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android AsyncTask奇怪地发布重复项

2019-12-01 09:27:29  阅读:175  来源: 互联网

标签:synchronize android


我认为这不是一个容易的问题.
我将简要介绍一下正在发生的事.
假设我们在文件Byron.txt中有一个数据源:

SHE walks in beauty, like the night
Of cloudless climes and starry skies;
And all that ‘s best of dark and bright
Meet in her aspect and her eyes:
Thus mellow’d to that tender light
Which heaven to gaudy day denies.

这段代码在AsyncTask中执行:

final ArrayList<Record> poem = new ArrayList<Record>();
final Object objectLock = new Object();
private Record rec = new Record();

@Override
protected Void doInBackground(Void... args) {
    String line = null;
    int i;
    int last;

    try {
        process = Runtime.getRuntime().exec("cat Byron.txt");
        bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()), 8192);

        synchronized (objectLock) {
            poem.clear();
            last = i = poem.size() - 1;
        }
        while(line = bufferedReader.readLine()) != null) {
            rec.setString(line);
            synchronized (objectLock) {
                last++;
                poem.add(last, rec);
            }

            while(!bPause && i < last) {
                i++;
                publishProgress(poem.get(i));
            }
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

@Override
protected synchronized void onProgressUpdate(Record... m) {
    if(m.length > 0) {
        mContext.mTable.appendRow(m[0]);
    }

}

UI中有一个TableLayout,每次我们得到新行时,都会向其中添加一个新的TableRow.
这是我们在用户界面中看到的输出:

SHE walks in beauty, like the night
Of cloudless climes and starry skies;
Of cloudless climes and starry skies;
Of cloudless climes and starry skies;
Thus mellow’d to that tender light
Thus mellow’d to that tender light

然后我们进入调试器,看看它为什么会发生.
有时,已同步的(objectLock)被跳过,循环继续进行.
没有发布,因为我已经赶上了最后.
之后,该块执行的次数与被跳过的次数相同,
,但是原始行丢失了,而是添加了当前行来多次写诗
然后,所有新行都会发布,直到我再次抓住最后一个.

因此,您看到我遵循了代码,并且可以解释发生了什么,这里的问题是:为什么跳过该块?为什么?
我希望同步块在执行之前会停滞.
至少这就是我对同步(objectLock)功能的理解
即使不使用wait()和notify()

我不假装在此处打开讨论(尽管如果您愿意,我们可以在聊天区域中打开一个讨论)
如果您在代码中发现错误,请回答问题以告知我.

笔记:

>需要同步,因为在应用程序中的其他位置,用户可能希望通过电子邮件发送到目前为止获得的信息.
>用户可以暂停发布(暂停);那是while循环,只有bPause为false时,我才最后跟随.

解决方法:

我决定发布答案.即使我为它的简单而感到尴尬.
只有在深入研究AsyncTask类和消息处理等之后,我才发现它.

I publish it in hope it will help people to check the basic things before jumping to
conclusions, and that someone out there will save himself half a day debugging because of
this post.

记录记录每次都相同.诗ArrayList的每个条目都具有相同的元素ID.由于所有内容都是相同的,因此内容一次全部更改了.
进度立即发布时,它会打印正确的字符串,即最后一个字符串.但是如果有些延迟导致进度稍后发布,则检索poem.get(i)记录将检索到另一个条目,但具有相同的指针,因此具有相同的内容.

解决的办法是创建一个新的记录每个循环.

标签:synchronize,android
来源: https://codeday.me/bug/20191201/2079850.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有