问题描述
一个游戏,我前一段时间写了与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
}
}
}
将其添加到的AndroidManifest.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的Android ANRS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!