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

时间:2015-09-15 10:08:25

标签: android multithreading view main freeze

我在我的一个游戏窗口中有9个自定义视图(每个视图都扩展了View类)导致我的UI线程冻结,当我按下“播放”按钮时,应用程序冻结(当充气布局时)在“onCreateView”中,我正在使用片段),直到生成游戏窗口,这非常非常难看。

我正在尝试在一个单独的线程中执行此操作,但都是问题,Android不允许我从主(UI)线程创建新视图。

我尝试了很多东西,但我无法得到它,有人能告诉我如何实现这一目标吗? 非常感谢你

2 个答案:

答案 0 :(得分:0)

对于非常cpu密集的绘图,您可以使用。

http://developer.android.com/reference/android/view/SurfaceView.html

  

本课程的目的之一是提供一个表面   辅助线程可以渲染到屏幕上。

答案 1 :(得分:0)

我通过在AsyncTask中手动膨胀布局来解决它。我从" Play Window"中调用了AsyncTask。我在哪里展示" loading"查看并在" onPostExecute"我创建了#34;游戏窗口" (片段)并替换它。

一些虚拟代码(PlayFragment是GameFragment的前一个屏幕):

"点击播放按钮" (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;
    }
}

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