运行在一个处理器由code的Andr​​oid ANRS? [英] Android ANRs from code running in a Handler?

查看:143
本文介绍了运行在一个处理器由code的Andr​​oid ANRS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个游戏,我前一段时间写了与ANRS一个问题,调试建议他们到HTTP请求花费很长的时间(以及因此引起的ANR)。

A game I wrote some time ago has a problem with ANRs, and debugging suggests they're down to HTTP requests taking a long time (and thus causing the ANR).

我还以为是通过指定的HTTP code到一个Runnable从处理程序中调用,我会避免ANR - 但似乎这是不是这样的?

I'd thought that by assigning the HTTP code into a Runnable called from within a Handler, I'd could avoid the ANR - but it seems this isn't the case?

堆栈转储建议可运行/处理code仍是主线程中运行,因此还是引起ANRS ??

The stack dumps suggest the runnable/handler code is still running within the 'Main' thread and thus still causes ANRs??

它做的任务是异步的(上传高分和成就),因此可以开始,留给它自己的全部设备 - 什么是实现这一点,以便ANRS不会成为一个问题的最好方法

The task it's doing is asynchronous (uploading highscores and achievements) and so can be started and left to it's own devices entirely - what is the best way to implement this so that ANRs aren't going to become a problem?

一个主题建议,处理程序应该在应用程序类,而不是在游戏的活动创造 - 但我不能找到这些情况?

One topic suggested that the Handler should be created in the Application class and not within the Game's Activity - but I can't find any detail on the differences between those cases??

所有的想法大大AP preC。

All ideas greatly apprec.

P.S。扩展这个要问 - 我想与HTTP的ANR归结为手机被外的服务/网络/无线网络,因为我已经为这些请求短超时(他们是可有可无的,可重试后来!?)

p.s. extending this to ask - I assume an ANR relating to HTTP comes down to the phone being out-of-service/network/WiFi, because I've set a SHORT timeout for these requests (they're non-essential and can be retried later!?)

推荐答案

A 处理程序将执行code /每秒处理的默认(任何构造消息,而不尺蠖例如新处理器())在当前线程。这是在几乎所有情况下的主线程。如果你想在一个不同的线程来执行,你必须告诉它尺蠖线程它应该使用。

A Handler will execute code / handle messages per default (any constructor without Looper e.g. new Handler()) in the current thread. That is in almost every case the main thread. If you want it to execute in a different thread you have to tell it which Looper thread it should use.

Android有一个创建尺蠖<叫做工具类 HandlerThread / code>。

Android has a utility class called HandlerThread that creates a Thread with a Looper.

短的例子:

public class MyActivity extends Activity {
    private Handler mHandler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        HandlerThread handlerThread = new HandlerThread("background-handler");
        handlerThread.start();
        Looper looper = handlerThread.getLooper();
        mHandler = new Handler(looper);

        mHandler.post(new Runnable() {
            public void run() {
                // code executed in handlerThread
            }
        });
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // stops the HandlerThread
        mHandler.getLooper().quit();
    }
}

在情况下,你的任务只需要一些信息,不需要报到,我会用 IntentService 去。那些没有发疯,如果你的活动,生命周期将重新创建活动。

In case your task needs only a some information and does not need to report back, I'd go with an IntentService. Those don't go mad if your Activity-lifecycle recreates the Activity.

您会在它自己的文件中创建一个小的服务

You would create a small Service in it's own file

public class SaveService extends IntentService {
    public SaveService() {
        super("SaveService");
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        if ("com.example.action.SAVE".equals(intent.getAction())) {
            String player = intent.getStringExtra("com.example.player");
            int score = intent.getIntExtra("com.example.score", -1);
            magicHttpSave(player, score); // assuming there is an implementation here
        }
    }
}

将其添加到的Andr​​oidManifest.xml

<application ....

    <service android:name=".SaveService" />
</application>

而在你的code与

And in your code start it with

Intent intent = new Intent(this /* context */, SaveService.class);
intent.setAction("com.example.action.SAVE");
intent.putExtra("com.example.player", "John123");
intent.putExtra("com.example.score", 5123);
startService(intent);

IntentService#onHandleIntent()运行在后台线程已经这样你就不必操心了。

IntentService#onHandleIntent() runs on a background thread already so you don't have to bother about that.

这篇关于运行在一个处理器由code的Andr​​oid ANRS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆