Как избежать некоторых пользовательских представлений, замораживающих поток пользовательского интерфейса?

У меня есть 9 пользовательских представлений (расширяя класс View для каждого из них) в одном из моих игровых окон, которые вызывают зависание в моем потоке пользовательского интерфейса. Когда я нажимаю кнопку "Play", приложение зависает (при надувании макета в "onCreateView"). "Я использую фрагменты), пока не сгенерировано окно игры, что-то очень-очень уродливое.

Я пытаюсь сделать это в отдельном потоке, но все проблемы, Android не позволяет мне создавать новые представления из основного потока (UI).

Я пробовал так много вещей, но я не могу получить это, может кто-нибудь сказать мне, как этого добиться? большое спасибо

2 ответа

Для очень интенсивного рисования процессора вы можете использовать.

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

Одна из целей этого класса - предоставить поверхность, на которой вторичный поток может рендериться на экран.

Я решил это, вручную надувая макет в AsyncTask. Я вызываю AsyncTask из "Окна воспроизведения", где я показываю представление "загрузки", а в "onPostExecute" я создаю "Окно игры" (фрагмент) и заменяю его.

Немного фиктивного кода (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;
    }
}

Это первый подход, поэтому он может быть подвергнут рефакторингу, и многие вещи можно сделать лучше, но это зависит от вас.

Другие вопросы по тегам