如何避免一些自定义视图冻结UI线程



我在一个游戏窗口中有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;
    }
}

这是第一种方法,所以它可以被重构,很多事情可以用更好的方式完成,但这取决于你。

相关内容

  • 没有找到相关文章

最新更新