我在一个游戏窗口中有9个自定义视图(扩展每个视图类),导致我的UI线程冻结,当我按下"Play"按钮时,应用程序冻结(当在"onCreateView"中膨胀布局时,我使用Fragments),直到游戏窗口生成,这是非常非常丑陋的东西。
我试图在一个单独的线程中这样做,但都是问题,Android不允许我在主(UI)线程外创建新视图。
我试了很多东西,但我不能得到它,谁能告诉我如何实现这一点?非常感谢
对于cpu非常密集的绘图,您可以使用。
http://developer.android.com/reference/android/view/SurfaceView.html这个类的目的之一是提供一个表面,在这个表面上次要线程可以渲染到屏幕。
我通过在AsyncTask中手动膨胀布局来解决这个问题。我从"播放窗口"中调用AsyncTask,在这里我显示"加载"视图,在"onPostExecute"中我创建"游戏窗口"(片段)并替换它。
一些虚拟代码(PlayFragment是GameFragment的前一个屏幕):
"Play button click" (PlayFragment):
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_play:
Bundle bundle = new Bundle();
bundle.putSerializable(ARG_SELECTED_GAME, selectedGame);
rlLoadingGame.setVisibility(View.VISIBLE);
GameFragment gameFragment = GameFragment.newInstance(selectedGame);
gameFragment.loadGame(activity, bundle);
break;
}
}
loadGame方法(GameFragment):
public void loadGame(Activity activity, Bundle bundle) {
this.activity = activity;
if (bundle != null) {
currentGame = (Game) bundle.getSerializable(ARG_SELECTED_GAME);
}
new GenerateGame(bundle).execute();
}
GenerateGame AsyncTask (GameFragment):
class GenerateGame extends AsyncTask<Void, Void>, View> {
private Bundle bundle;
public GenerateGame(Bundle bundle) {
this.bundle = bundle;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// do your stuff
}
@Override
protected View doInBackground(Void... params) {
View child = activity.getLayoutInflater().inflate(R.layout.game_fragment_layout, null);
// do all your heavy load stuff
return child;
}
@Override
protected void onPostExecute(View layout) {
super.onPostExecute(layout);
// initialize and set all UI elements
replaceFragment(layout, bundle);
}
}
replaceFragment方法(GameFragment):
private void replaceFragment(View newView, Bundle bundle) {
fragmentLayout = newView;
// call to fragment manager replace/add or required method passing this as Fragment to replace and the bundle if needed
}
onCreateView (GameFragment):
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (fragmentLayout != null) {
return fragmentLayout;
} else {
return null;
}
}
这是第一种方法,所以它可以被重构,很多事情可以用更好的方式完成,但这取决于你。