0

To preface, I am student and pretty new to Java/Programming. I am very new to the android framework. I want 5 dice ImageView's to cycle on a loop to appear like they are rolling. I believe the main issue I am having is that my UI changes are happening outside of onCreate(). Is there a way to bridge the MainActivity and a separate Java class?

MainActivity

  super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        Button rollButton = (Button) findViewById(R.id.rollButton);
        rollButton.setOnClickListener( new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Thread die1 = new Thread((Runnable) new ShipDriver(0));

                die1.start();

Separate Java Class

public class ShipDriver implements Runnable {
    ImageView imageView;
    ImageView imageView2;
    ImageView imageView3;
    ImageView imageView4;
    ImageView imageView5;
    int dieIndex;
    int rolled;
    Handler myHandlerObj;
    Runnable runnable;


    public static final Random RANDOM = new Random();


    public ShipDriver(int tdieIndex) {

        dieIndex = tdieIndex;

    }


    public void run() {
        rolled = randomDiceValue();
        Handler myHandlerObj = new Handler(Looper.getMainLooper());

        for(int i=0; i<40; i++) {

            try {

                Thread.sleep(1000);
            }catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (dieIndex == 0) {
                myHandlerObj.post(new Runnable() {
                    @Override
                    public void run() {
                        switch (rolled) {
                            case 1:

                                imageView.setImageResource(R.drawable.die1);
                            case 2:
                                imageView.setImageResource(R.drawable.die2);
                            case 3:
                                imageView.setImageResource(R.drawable.die3);
                            case 4:
                                imageView.setImageResource(R.drawable.die4);
                            case 5:
                                imageView.setImageResource(R.drawable.die5);
                            case 6:
                                imageView.setImageResource(R.drawable.die6);

                    }
                }
                });
            if (dieIndex == 1) {
                myHandlerObj.post(new Runnable() {
                    @Override
                    public void run() {
                        switch (rolled) {
                            case 1:
                                imageView2.setImageResource(R.drawable.die1);
                            case 2:
                                imageView2.setImageResource(R.drawable.die2);
                            case 3:
                                imageView2.setImageResource(R.drawable.die3);
                            case 4:
                                imageView2.setImageResource(R.drawable.die4);
                            case 5:
                                imageView2.setImageResource(R.drawable.die5);
                            case 6:
                                imageView2.setImageResource(R.drawable.die6);
                        }
                    }
                });
            }

...... 

In logcat im getting this error:

attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference

Im kinda at a loss with this. Any insight would be greatly appreciated.

Fate4g63
  • 1
  • 1
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Martin Zeitler May 22 '19 at 00:27

4 Answers4

0

I think the problem is that you're trying to make UI changes outside of the main thread, and you can't do that on Android, try to use runOnUiThread instead, like the example below:

runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                    }
                }
Shermano
  • 1,100
  • 8
  • 31
0

Have you tried to Set a Context? I think this would Help...

Try something like Context context.

context.imageview.setImageResource

or

this.imageview.setImageResource

Just a guess

Update: Use this as example

MainActivity

public static ImageView Warning_image;
public static TextView Warning_text;
public static Handler mainHandler = new Handler();
@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Warning_image = findViewById(R.id.Status_Image);
    Warning_text = findViewById(R.id.Warning_text);

    Runnable rcWarningControl = new cWarningControl();

    rcWarningControl.run();

cWarningControl

public class cWarningControl extends MainActivity implements Runnable {
@Override
public void run() {
    while(true)
    {
     if (cGlobal_values.bBT_NOADAPTER) {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    MainActivity.Warning_image.setImageResource(R.mipmap.warnung_bt_red);
                    MainActivity.Warning_text.setText(R.string.warning_BT_NO_Adapter);
                }
            });

        }
        if (!cGlobal_values.bBT_GenState_on) {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    MainActivity.Warning_image.setImageResource(R.mipmap.warnung_bt_red);
                    MainActivity.Warning_text.setText(R.string.warning_BT_OFF);
                }
            });

        }
        if (cGlobal_values.bBT_GenState_on) {

            if (cGlobal_values.bBT_ConState_connected) {
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        MainActivity.Warning_image.setImageResource(R.mipmap.warnung_bt_green);
                        MainActivity.Warning_text.setText(R.string.warning_BT_ON_CON);
                    }
                });

            } else {
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        MainActivity.Warning_image.setImageResource(R.mipmap.warnung_bt_yellow);
                        MainActivity.Warning_text.setText(R.string.warning_BT_ON_NOCON);
                    }
                });
            }
        }
        Log.d(TAG, "run: ");
        sleep(1000);
  }      
}

}

BUT

The strings (R.string.XXX) you have to create in res or just make them by yourself. Same for the image obj.

Alpha-Centauri
  • 316
  • 2
  • 13
  • I just gave this a go. specifically mainActivity.imageView.setImageResource. IDE isnt throwing any errors but on run the logcat is giving me a: attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference – Fate4g63 May 21 '19 at 23:03
  • I followed your code and subbed mine in. I am still getting a nullpointer exception when my code gets to `MainActivity.imageView.setImageResource(R.drawable.die#);` My build output is also giving me errors: error: non-static variable imageView cannot be referenced from a static context I have some other questions aswell. Why did you declare your variable in your MainActivity static? Also do you mind clarifying your "but" sentence? – Fate4g63 May 23 '19 at 00:36
0

The error that you are showing is comes when the object is not initialised. First you initialise your imageview objects.The error you are showing is not a thread error.

  • I kinda figured that out. I am just struggling to get it fixed so my app will run. When Iam looking at the logcat I can see the game logic is at work. The random die image is chosen and the switch cases are working but when it hits setImageResources it fails. At this point my code is different compared to the code i posted above. – Fate4g63 May 23 '19 at 03:02
0

I figured out my null point exception. My findViewByID (for the imageViews) was improperly set. I was having them look for R.drawable.imgs. It needed to be a R.id.imageview.

However I am running into a new issue where the images are not cycling. I guess Ill do some more digging into that. I am just glad to have made progress after 40ish hours of bashing my head on this problem. Below is the code for my solution.


import android.annotation.SuppressLint;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Switch;


import java.util.Random;

public class MainActivity extends AppCompatActivity {

    public static ImageView imageView1;
    public static Handler mainHandler = new Handler();
    Button rollDie;


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

        imageView1 = (ImageView) findViewById(R.id.imageView1);

        rollDie = findViewById(R.id.rollDie);
        rollDie.setOnClickListener( new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Runnable die1 = new ShipDriver(0);
                die1.run();


            }
        });
    }
}

ShipDriver class:

package com.example.bernh.cptshipmatecrew;

import android.annotation.SuppressLint;
import android.os.Handler;
import android.widget.ImageView;

import java.util.Random;

public class ShipDriver extends MainActivity implements Runnable {
    int dieIndex;
    Random random;
    int rolled;
    ImageView imageView1;
    Handler mainHandler = new Handler();


    public ShipDriver(int dieIndex) {
        this.dieIndex = dieIndex; //why do we declare this. Is this shipdriver obj or MainObj


    }

    @SuppressLint("ResourceType")
    @Override
    public void run() {
        Random random = new Random();


        rolled = random.nextInt(6) + 1;

        for (int i = 0; i < 30; i++) {
            try {
                Thread.sleep(500);
            } catch(Exception e) {
                e.printStackTrace();
            }

            if (dieIndex == 0) {
                mainHandler.post(new Runnable() {
                                       @Override
                    public void run() {
                        switch (rolled) {
                            case 1:
                                MainActivity.imageView1.setImageResource(R.drawable.die1);
                                break;
                            case 2:
                                MainActivity.imageView1.setImageResource(R.drawable.die2);
                                break;
                            case 3:
                                MainActivity.imageView1.setImageResource(R.drawable.die3);
                                break;
                            case 4:
                                MainActivity.imageView1.setImageResource(R.drawable.die4);
                                break;
                            case 5:
                                MainActivity.imageView1.setImageResource(R.drawable.die5);
                                break;
                            case 6:
                                MainActivity.imageView1.setImageResource(R.drawable.die6);
                                break;

                        }
                    }
                });
            }
//            if (dieIndex == 1) {
//                mainHandler.post(new Runnable() {
//                    @Override
//                    public void run() {
//                        switch (rolled) {
//                            case 1:
//                                MainActivity.imageView.setImageResource(R.drawable.die1);
//                            case 2:
//                                MainActivity.imageView.setImageResource(R.drawable.die2);
//                            case 3:
//                                MainActivity.imageView.setImageResource(R.drawable.die3);
//                            case 4:
//                                MainActivity.imageView.setImageResource(R.drawable.die4);
//                            case 5:
//                                MainActivity.imageView.setImageResource(R.drawable.die5);
//                            case 6:
//                                MainActivity.imageView.setImageResource(R.drawable.die6);
//
//                        }
//                    }
//
//                });
//            }
//            if (dieIndex == 2) {
//                mainHandler.post(new Runnable() {
//                    @Override
//                    public void run() {
//                        switch (rolled) {
//                            case 1:
//                                MainActivity.imageView.setImageResource(R.drawable.die1);
//                            case 2:
//                                MainActivity.imageView.setImageResource(R.drawable.die2);
//                            case 3:
//                                MainActivity.imageView.setImageResource(R.drawable.die3);
//                            case 4:
//                                MainActivity.imageView.setImageResource(R.drawable.die4);
//                            case 5:
//                                MainActivity.imageView.setImageResource(R.drawable.die5);
//                            case 6:
//                                MainActivity.imageView.setImageResource(R.drawable.die6);
//
//                        }
//                    }
//
//                });
//            }
//            if (dieIndex == 3) {
//                mainHandler.post(new Runnable() {
//                    @Override
//                    public void run() {
//                        switch (rolled) {
//                            case 1:
//                                MainActivity.imageView.setImageResource(R.drawable.die1);
//                            case 2:
//                                MainActivity.imageView.setImageResource(R.drawable.die2);
//                            case 3:
//                                MainActivity.imageView.setImageResource(R.drawable.die3);
//                            case 4:
//                                MainActivity.imageView.setImageResource(R.drawable.die4);
//                            case 5:
//                                MainActivity.imageView.setImageResource(R.drawable.die5);
//                            case 6:
//                                MainActivity.imageView.setImageResource(R.drawable.die6);
//
//                        }
//                    }
//
//                });
//            }
//            if (dieIndex == 4) {
//                mainHandler.post(new Runnable() {
//                    @Override
//                    public void run() {
//                        switch (rolled) {
//                            case 1:
//                                MainActivity.imageView.setImageResource(R.drawable.die1);
//                            case 2:
//                                MainActivity.imageView.setImageResource(R.drawable.die2);
//                            case 3:
//                                MainActivity.imageView.setImageResource(R.drawable.die3);
//                            case 4:
//                                MainActivity.imageView.setImageResource(R.drawable.die4);
//                            case 5:
//                                MainActivity.imageView.setImageResource(R.drawable.die5);
//                            case 6:
//                                MainActivity.imageView.setImageResource(R.drawable.die6);
//
//                        }
//                    }
//
//                });
//            }

        }
    }
}
Fate4g63
  • 1
  • 1