我前一段时间写的游戏存在ANR问题,调试表明它们是由于HTTP请求花费了很长时间(从而导致了ANR)。
我以为通过将HTTP代码分配给从Handler中调用的Runnable中,我可以避免使用ANR-但似乎不是这样吗?
堆栈转储表明可运行/处理程序代码仍在“主”线程中运行,因此仍会导致ANR?
它正在执行的任务是异步的(上传高分和成就),因此可以完全将其启动并留给其自己的设备-实现此目标以使ANR不会成为问题的最佳方法是什么?
一个主题建议处理程序应该在Application类中创建,而不是在游戏的Activity中创建-但是我找不到关于这两种情况之间差异的详细信息?
所有的想法都很赞赏。
p.s.将其扩展为询问-我假设与HTTP有关的ANR归因于电话停止服务/网络/WiFi,因为我已为这些请求设置了SHORT超时(它们不是必需的,可以重试)之后!?)
最佳答案
Handler
将在当前线程中默认执行代码/处理消息(默认情况下,任何没有Looper
的构造函数,例如new Handler()
)。几乎在每种情况下,这都是主线程。如果希望它在其他线程中执行,则必须告诉它应使用哪个Looper
线程。
Android有一个名为HandlerThread
的实用程序类,该实用程序类使用Thread
创建一个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
。如果您的Activity-lifecycle重新创建Activity,那么这些都不会发疯。您将在自己的文件中创建一个小的
Service
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>
然后在您的代码中以
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()
已经在后台线程上运行,因此您不必为此而烦恼。关于android - 来自在处理程序中运行的代码的Android ANR?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13368762/