学习Android:使用BroadcastReceiver冻结UI

正如我在上一篇文章中提到的那样,我最近在Android应用中编写了一些代码,以在服务处理带有链接的推文时通知BroadcastReceiver ,但在实现此功能时,每次发生时我都设法冻结了UI。

我犯了一个愚蠢的错误(事后看来),因为我意识到我不应该在BroadcastReceiver.onReceive中做很多逻辑,因为那部分代码是在UI线程上执行的。

引发广播消息的服务代码与上一篇文章相同:

public class TweetService extends IntentService {
    ...
    @Override
    protected void onHandleIntent(Intent intent) {
        StatusListener listener = new UserStreamListener() {
           // override a whole load of methods - removed for brevity
 
            public void onStatus(Status status) {
                String theTweet = status.getText();
                if (status.getText().contains("http://")) {
                    Intent tweetMessage = new Intent(TweetTask.NEW_TWEET);
                    tweetMessage.putExtra(android.content.Intent.EXTRA_TEXT, status.getText());
                    sendBroadcast(tweetMessage);
                }
 
            }
        };
 
        // code to connect to the twitter streaming API
    }
}

然后由BroadcastReceiver像这样处理:

public class MyActivity extends Activity {
    protected void onPause() {
        super.onPause();
        if (dataUpdateReceiver != null) unregisterReceiver(dataUpdateReceiver);
    }
 
    protected void onResume() {
        super.onResume();
        if (dataUpdateReceiver == null) dataUpdateReceiver = new DataUpdateReceiver();
        IntentFilter intentFilter = new IntentFilter(TweetTask.NEW_TWEET);
        registerReceiver(dataUpdateReceiver, intentFilter);
    }
 
    private class DataUpdateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(TweetTask.NEW_TWEET)) {
                Pattern p = Pattern.compile("(http://[^\\s]+)");
                String theTweet = intent.getStringExtra(TweetTask.NEW_TWEET);
                Matcher matcher = p.matcher(theTweet);
 
                int startIndex = -1;
                int endIndex = -1;
                while (matcher.find()) {
                    startIndex = matcher.start();
                    endIndex = matcher.end();
                }
 
                if (startIndex != -1 && endIndex != -1) {
                    String resolvedUrl = resolveUrl(theTweet.substring(startIndex, endIndex));
                    saveToDatabase(resolvedUrl);
                    updateUI(resolvedUrl);
                }
            }
        }
    }
}

特别是'resolveUrl'行可能是引起此问题的那一行,因为它进行网络调用以解析来自链接缩短器的URL

要停止屏幕冻结,我只需要将大多数代码从BroadcastReceiver移到TweetService中:

public class TweetService extends IntentService {
    ...
    @Override
    protected void onHandleIntent(Intent intent) {
        StatusListener listener = new UserStreamListener() {
           // override a whole load of methods - removed for brevity
 
            public void onStatus(Status status) {
                String theTweet = status.getText();
                if (status.getText().contains("http://")) {
                    Pattern p = Pattern.compile("(http://[^\\s]+)");
                    Matcher matcher = p.matcher(theTweet);
 
                    int startIndex = -1;
                    int endIndex = -1;
                    while (matcher.find()) {
                        startIndex = matcher.start();
                        endIndex = matcher.end();
                    }
 
                    if (startIndex != -1 && endIndex != -1) {
                        String resolvedUrl = resolveUrl(theTweet.substring(startIndex, endIndex));
                        saveToDatabase(resolvedUrl);
 
                        Intent tweetMessage = new Intent(TweetTask.NEW_TWEET);
                        tweetMessage.putExtra(android.content.Intent.EXTRA_TEXT, resolvedUrl);
                        sendBroadcast(tweetMessage);
                    }
                }
            }
        };
 
        // code to connect to the twitter streaming API
    }
}

然后,BroadcastReceiver的代码变得更加简单,这意味着我们在UI线程上的工作量减少了:

private class DataUpdateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(TweetTask.NEW_TWEET)) {
                String url = intent.getStringExtra(TweetTask.NEW_TWEET);
                updateUI(url);
            }
        }
    }

UI的冻结消失了!

参考资料: 学习Android:使用Mark Needham博客的JCG合作伙伴Markh Needham 的BroadcastReceiver冻结UI

翻译自: https://www.javacodegeeks.com/2012/01/learning-android-freezing-ui-with.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值