Тема во фрагменте вызывается только один раз - PullRequest
0 голосов
/ 26 августа 2018

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

new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(menuActivity, "HELLO", Toast.LENGTH_SHORT).show();
        }
    });

Это будет выполняться только один раз, даже если Looper обычно должен поддерживать поток живым.Попытка вызвать Looper.prepare() внутри Handler приведет к RuntimeException, так как только один Looper разрешен для каждого потока. Редактировать: Моя цель - постоянно обновлять TextView каждую секунду.

Я также попробовал следующее:

Thread t = new Thread() {
        @Override
        public void run() {
            menuActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("-----------TEST");
                }

            }); 
        }
    };
t.start();

Но это будет выполняться только один раз.

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

Где мойошибка в каком-либо из этих фрагментов кода?

Этот вопрос не является дубликатом из-за того, что я представил совершенно другой фрагмент кода, который является основой проблемы, с которой я столкнулся.Кроме того, Looper более подробно объясняется в этой теме.

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

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

Экран макета

enter image description here

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/text_view_money"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:textColor="@android:color/black"
        android:textSize="20sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="30dp"
        android:layout_marginTop="30dp"
        android:orientation="horizontal">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="startUpdateTextViewMoney"
            android:text="Start" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="stopUpdateTextViewMoney"
            android:text="Stop" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/edit_text_money"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="setMoney"
            android:text="SET MONEY" />

    </LinearLayout>

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private static final int UPDATE_TEXT_MONEY_INTERVAL = 1000;

    private Handler mMainHandler;

    private TextView mTextViewMoney;
    private TextView mEditTextMoney;

    private String money;

    private Runnable mUpdateTextViewMoneyTask = new Runnable() {
        @Override
        public void run() {
            if (TextUtils.isEmpty(money)) {
                mTextViewMoney.setText(String.valueOf(SystemClock.elapsedRealtime()));
            } else {
                mTextViewMoney.setText(money);
                money = null;
            }
            mMainHandler.postDelayed(this, UPDATE_TEXT_MONEY_INTERVAL);
        }
    };

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

        mTextViewMoney = findViewById(R.id.text_view_money);
        mEditTextMoney = findViewById(R.id.edit_text_money);

        mMainHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    protected void onStop() {
        super.onStop();
        stopUpdateTextViewMoney(null);
    }

    public void startUpdateTextViewMoney(View view) {
        mMainHandler.post(mUpdateTextViewMoneyTask);
    }

    public void stopUpdateTextViewMoney(View view) {
        mMainHandler.removeCallbacks(mUpdateTextViewMoneyTask);
    }

    public void setMoney(View view) {
        String money = mEditTextMoney.getText().toString();
        this.money = !TextUtils.isEmpty(money) ? money : "";
    }
}
  • Когда пользователи нажимают кнопку Пуск, приложение будет обновлять представление текста каждую секунду
  • Когда пользователи нажимают кнопку «Стоп», приложение перестает обновлять представление текста.
  • Если пользователи хотят установить новые деньги для отображения в следующий раз, просто введите текст редактирования, затем нажмите «Установить деньги»..
0 голосов
/ 26 августа 2018

Это будет выполняться только один раз, даже если Looper обычно должен поддерживать поток живым.,Looper - это , поддерживающий поток живым.Если основной поток не поддерживается, ваше приложение будет закрыто.Looper действительно не , однако, обеспечивает повторное выполнение Runnable, опубликованных в Handler / Thread, с которым он связан.Каждый Runnable выполняется ровно один раз.Если вы хотите выполнить один и тот же Runnable несколько раз, вы должны опубликовать его несколько раз.Например:

Handler mainThreadHandler = new Handler(Looper.getMainLooper());
Runnable doToast = new Runnable() {
        @Override
        public void run() {
            Toast.makeText(menuActivity, "HELLO", Toast.LENGTH_SHORT).show();
        }
    });
mainThreadHandler.post(doToast); // Queue the first execution of the code in the Runnable's run() method. 
mainThreadHandler.post(doToast); // Queue the second execution of the code in the Runnable's run() method.
...