OnClickListener вызывает бесконечный цикл - PullRequest
0 голосов
/ 21 октября 2018

Я работаю над приложением, которое позволяет пользователю выбирать между несколькими анимациями перед установкой выбора в качестве текущих запущенных живых обоев.

Я просмотрел ссылки с похожими вопросами, такими как: callЖивые обои в приложении

И: Установка живых обоев программно

Они описывают, как сделать выбор, но не ошибку, которую я вижу.

Первый экран, отображаемый для пользователя, - это экран выбора, на котором отображаются несколько обоев.У каждого фонового рисунка есть кнопка, которую пользователь может щелкнуть, что указывает на выбор фонового рисунка.

Каждая кнопка имеет уникальный идентификатор.Каждый найден и назначен экземпляру объекта Button, и каждый зарегистрирован с помощью OnClickListener.

После нажатия кнопки я использую оператор switch, чтобы определить, какая кнопка была нажата, я создаю новый Intent, укажите, какой класс обоев я хочу запустить, и я запускаю действие.

Когда я запускаю это в эмуляторе, приложение загружается, как и ожидалось.Я вижу свой экран выбора, и он правильно отображает различные варианты обоев.Проблема возникает, когда я выбираю обои для запуска.Как только я нажимаю на кнопку, дисплей становится белым и остается в этом положении до тех пор, пока я не выключу отладчик.

Запустив это в режиме отладки, я обнаружил, что после нажатия на кнопку выбора код выполняетоператор switch выполняет создание намерения, которое вызывает метод startActivity (intent), а затем прерывается.Затем код переходит через классы View.java, Handler.java и Looper.java, где он, наконец, зацикливается навсегда в классе Looper.java в цикле for, который имеет дело с очередью сообщений.

ЭтоMainActivity, где я устанавливаю начальный вид компоновки, устанавливаю свои кнопки и создаю onClickListener:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.selection);

    // Capture our buttons from the selection layout
    Button button_1 = (Button)findViewById(R.id.set1);
    button_1.setOnClickListener(this);

    // Capture our buttons from the selection layout
    Button button_2 = (Button)findViewById(R.id.set2);
    button_2.setOnClickListener(this);

    // Capture our buttons from the selection layout
    Button button_3 = (Button)findViewById(R.id.set3);
    button_3.setOnClickListener(this);

}

// Implement the OnClickListener callback
public void onClick(View v) {
    switch(v.getId())
    {
        //If button_1 was selected, set the first wallpaper.
        case R.id.set1 :
            setContentView(R.layout.activity_main);
            Intent intent = new Intent(
                    WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
            intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
                    new ComponentName(this, Wallpaper1.class));
            startActivity(intent);
            break;
        //If button_2 was selected, set the second wallpaper.
        case R.id.set2 :
            setContentView(R.layout.activity_main);
            intent = new Intent(
                    WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
            intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
                    new ComponentName(this, Wallpaper2.class));
            startActivity(intent);
            break;
        //If the Cuba button was selected, set the Cuba wallpaper.
        case R.id.set3 :
            setContentView(R.layout.activity_main);
            intent = new Intent(
                    WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
            intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
                    new ComponentName(this, Wallpaper3.class));
            startActivity(intent);
            break;
    }
}

Вот цикл сообщений, в котором выполнение застревает с бесконечной итерацией:

for (;;) {
        Message msg = queue.next(); // might block
        if (msg == null) {
            // No message indicates that the message queue is quitting.
            return;
        }

        // This must be in a local variable, in case a UI event sets the logger
        final Printer logging = me.mLogging;
        if (logging != null) {
            logging.println(">>>>> Dispatching to " + msg.target + " " +
                    msg.callback + ": " + msg.what);
        }

        final long traceTag = me.mTraceTag;
        if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
            Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
        }
        try {
            msg.target.dispatchMessage(msg);
        } finally {
            if (traceTag != 0) {
                Trace.traceEnd(traceTag);
            }
        }

        if (logging != null) {
            logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
        }

        // Make sure that during the course of dispatching the
        // identity of the thread wasn't corrupted.
        final long newIdent = Binder.clearCallingIdentity();
        if (ident != newIdent) {
            Log.wtf(TAG, "Thread identity changed from 0x"
                    + Long.toHexString(ident) + " to 0x"
                    + Long.toHexString(newIdent) + " while dispatching to "
                    + msg.target.getClass().getName() + " "
                    + msg.callback + " what=" + msg.what);
        }

        msg.recycleUnchecked();
    }

Кажется, код не замечает событие click до тех пор, пока он не пройдет корректно через оператор switch.

Как я могу получить это, чтобы правильно вызвать Intent?

...