«Только исходный поток, создавший иерархию представлений, может касаться его представлений.» Как решить эту проблему в моем случае? - PullRequest
0 голосов
/ 20 октября 2019

У меня следующая проблема.

У меня есть RewardedVideoListener в Class1 и я хочу сделать несколько просмотров INVISIBLE в Class2, как только воспроизводится видео с вознаграждением.

Проблема в том, что я получаю следующую ошибку:

2019-10-20 22:13:48.336 13565-13587/com.myapp.nameE/AndroidRuntime: FATAL EXCEPTION: Thread-2
    Process: com.fujigames.memesoundboard, PID: 13565
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
        at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6855)
        at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1075)
        at android.view.ViewGroup.invalidateChild(ViewGroup.java:5242)
        at android.view.View.invalidateInternal(View.java:13574)
        at android.view.View.invalidate(View.java:13538)
        at android.view.View.setFlags(View.java:11447)
        at android.view.View.setVisibility(View.java:8001)
        at com.myapp.name.MainActivity.onRewardedVideoAdRewarded(MainActivity.java:449)
        at com.ironsource.mediationsdk.sdk.ListenersWrapper$7.run(ListenersWrapper.java:198)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at com.ironsource.mediationsdk.sdk.ListenersWrapper$CallbackHandlerThread.run(ListenersWrapper.java:499)

Вот метод в Class1, который вызывается, когда видео с вознаграждением только что закончилось:

@Override
public void onRewardedVideoAdRewarded(Placement placement) {
    Class2 cl2 = new Class2();

    cl2.greyBackgroundcl2 = (ImageView) findViewById(R.id.greyBackgroundcl2);
    cl2.adtextcl2 = (TextView)findViewById(R.id.adtextcl2);
    cl2.showcl2 = (Button) findViewById(R.id.showVideocl2);

    cl2.showcl2.setVisibility(View.INVISIBLE);
    cl2.greyBackgroundcl2.setVisibility(View.INVISIBLE);
    cl2.adtextcl2.setVisibility(View.INVISIBLE);
}

И этоis Class2 (A Fragment)

public class Class2 extends Fragment {

    public Button showcl2;
    public ImageView greyBackgroundcl2;
    public TextView adtextcl2;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView=inflater.inflate(R.layout.tab5_layout,container,false);
        mLayout=rootView.findViewById(R.id.tab5);
    }
}

Я довольно новичок в Android Studio, поэтому я попытался исправить это самостоятельно, но не нашел хороших ответов в Google.

Как предотвратить сбой приложения? (Вылетает, как только заканчивается видео с наградами)

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

Похоже, вы пытаетесь найти элементы вида из Fragment (то есть Class2 в вашем случае), которые еще не раздуты.

Я хотел бы порекомендовать сохранить переменную public static boolean в Class1, где воспроизводится видео с наградами, и использовать его в качестве индикатора в Class2. Давайте возьмем пример следующим образом.

public static boolean isRewardVideoPlayed = false;

@Override
public void onRewardedVideoAdRewarded(Placement placement) {
    isRewardVideoPlayed = true;
}

Теперь в onCreateView вашего Class2 проверьте значение isRewardVideoPlayed и, основываясь на этом значении, установите видимость представлений.

public class Class2 extends Fragment {

    public Button showcl2;
    public ImageView greyBackgroundcl2;
    public TextView adtextcl2;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView=inflater.inflate(R.layout.tab5_layout,container,false);
        mLayout=rootView.findViewById(R.id.tab5);

        greyBackgroundcl2 = (ImageView) rootView.findViewById(R.id.greyBackgroundcl2);
        adtextcl2 = (TextView)rootView.findViewById(R.id.adtextcl2);
        showcl2 = (Button) rootView.findViewById(R.id.showVideocl2);

        if(Class1.isRewardVideoPlayed) {
            showcl2.setVisibility(View.INVISIBLE);
            greyBackgroundcl2.setVisibility(View.INVISIBLE);
            adtextcl2.setVisibility(View.INVISIBLE);
        }
    }
}

Если оба ваших Fragment видны одновременно, вы можете подумать о включении сегмента кода в вашу функцию onResume, чтобы он вступил в силу, как только видео награды будет закончено. игры.

@override
public void onResume() {
    super.onResume();

    if(Class1.isRewardVideoPlayed) {
        showcl2.setVisibility(View.INVISIBLE);
        greyBackgroundcl2.setVisibility(View.INVISIBLE);
        adtextcl2.setVisibility(View.INVISIBLE);
    }
}

Надеюсь, это поможет!

0 голосов
/ 20 октября 2019

Изменить метод onRewardedVideoAdRewarded следующим образом

@Override
public void onRewardedVideoAdRewarded(Placement placement) {
final Class2 cl2 = new Class2();

cl2.greyBackgroundcl2 = (ImageView) findViewById(R.id.greyBackgroundcl2);
cl2.adtextcl2 = (TextView)findViewById(R.id.adtextcl2);
cl2.showcl2 = (Button) findViewById(R.id.showVideocl2);

MainActivity.this.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        cl2.showcl2.setVisibility(View.INVISIBLE);
        cl2.greyBackgroundcl2.setVisibility(View.INVISIBLE);
        cl2.adtextcl2.setVisibility(View.INVISIBLE);

    }
});
}
...