0

I have written a small app in Android Studio. If I start the app in the emulator, then I get an exception. The application simply stops.

The source code looks as follows:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private int points, round, countdown;
    private static final int FROG_ID = 212121;
    private Random rnd = new Random();
    private Handler handler = new Handler();


    private Runnable runnable = new Runnable(){
        @Override
        public void run(){
            countdown();
        }
    };

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


    private void newGame(){
        points = 0;
        round = 1;
        initRound();
    }

    private void initRound(){
        countdown = 10;
        ViewGroup container = (ViewGroup) findViewById(R.id.container);
        container.removeAllViews();
        WimmelView wv = new WimmelView(this);
        container.addView(wv, ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        wv.setImageCount(5*(10+round));
        ImageView frog = new ImageView(this);
        frog.setId(FROG_ID);
        frog.setImageResource(R.drawable.frog1);
        frog.setScaleType(ImageView.ScaleType.CENTER);
        float scale = getResources().getDisplayMetrics().density;
        FrameLayout.LayoutParams lp= new FrameLayout.LayoutParams(Math.round(64*scale),Math.round(61*scale));
        lp.leftMargin = rnd.nextInt(container.getWidth()-64);
        lp.topMargin = rnd.nextInt(container.getHeight()-61);
        lp.gravity = Gravity.TOP + Gravity.START;
        frog.setOnClickListener(this);
        container.addView(frog, lp);
        handler.postDelayed(runnable, 1000-round*50);
        update();

    }

    private void fillTextView(int id, String text){
        TextView tv = (TextView) findViewById(id);
        tv.setText(text);
    }

    private void update(){
        fillTextView(R.id.points, Integer.toString(points));
        fillTextView(R.id.round, Integer.toString(round));
        fillTextView(R.id.countdown,
                Integer.toString(countdown*1000));
    }

    private void showStartFragment(){
        ViewGroup container = (ViewGroup) findViewById(R.id.container);
        container.removeAllViews();
        container.addView(
                getLayoutInflater().
                        inflate(R.layout.fragment_start, null));
        container.findViewById(R.id.start).setOnClickListener(this);
    }

    private void showGameOverFragment(){
        ViewGroup container = (ViewGroup) findViewById(R.id.container);
        container.addView(
                getLayoutInflater().
                        inflate(R.layout.fragment_gameover, null));
        container.findViewById(play_again).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if(view.getId()==R.id.start){
            startGame();
        }else if(view.getId()==R.id.play_again){
            showStartFragment();
        }else if(view.getId()==FROG_ID){
            handler.removeCallbacks(runnable);
            Toast.makeText(this,R.string.kissed, Toast.LENGTH_SHORT).show();
            //showToast(R.string.kissed);
            points += countdown*1000;
            round++;
        }
        initRound();
    }


    private void startGame() {
        newGame();
    }

    private void countdown(){
        countdown--;
        update();
        if(countdown<=0){
            //frog.setOnClickListener(null);
            showGameOverFragment();
        }else {
            handler.postDelayed(runnable, 1000-round*50);
        }
    }

    @Override
    protected  void onPause(){
        super.onPause();
        handler.removeCallbacks(runnable);
    }
}

At the beginning I came so far that I could at least press on start, now I am not at all more in the application pure ... I have tried to googlen what it could be, but I have not succeeded in doing so. I also get a error message at the point frog.setId (FROG_ID).

In addition, I have yet another class, which implements images

public class WimmelView extends View {

    private Random rnd;
    private long randomSeed = 1;
    private int imageCount;
    private Paint paint = new Paint();


    private static  final int[]
            images = { R.drawable.frog2,
                      R.drawable.frog3,R.drawable.frog4,
                      R.drawable.frog5,R.drawable.frog6};

    public void setImageCount(int imageCount){
        this.imageCount = imageCount;
        randomSeed = System.currentTimeMillis();
        invalidate();
    }

    public WimmelView(Context context){
        super(context);
        paint.setAntiAlias(true);
    }

    @Override
    protected void onDraw(Canvas canvas){
        super.onDraw(canvas);
        rnd = new Random(randomSeed);
        for(int image:images){
            Bitmap bitmap =
                    BitmapFactory.decodeResource(getResources(),image);
            for(int i=0; i<imageCount/images.length; i++){
                float left = (float) (rnd.nextFloat()
                        *(getWidth()-bitmap.getWidth()));
                float top = (float) (rnd.nextFloat()
                        *(getWidth()-bitmap.getWidth()));
                canvas.drawBitmap(bitmap,left,top,paint);
            }
            bitmap.recycle();
        }
}
}

I hope someone sees the error and can help me ...

Roman Pokrovskij
  • 9,449
  • 21
  • 87
  • 142
  • Please provide your Exception from the Log Console. It will have highlighted blue words and line of code where issue is. – Sam Sep 20 '17 at 23:45
  • the only indication that I got is in the logcat: 09-20 23:03:42.401 5345-5345/com.java.test.kissthefrog E/AndroidRuntime: FATAL EXCEPTION: main Process: com.java.test.kissthefrog, PID: 5345 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.java.test.kissthefrog/com.java.test.kissthefrog .MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference – Berat Rex Haj Sep 21 '17 at 00:24
  • at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) – Berat Rex Haj Sep 21 '17 at 00:28
  • The error may be here Bitmap bitmap = BitmapFactory.decodeResource(getResources(),image); – Pramod J George Sep 21 '17 at 01:00
  • In how far can this be a problem? – Berat Rex Haj Sep 21 '17 at 01:07

3 Answers3

0

Your error is that the Content view is removing all children from the screen including the textviews of the score and points that you are trying to use. I just helped you move to fragments offline and ensured you were good to go. Goodluck.

Sam
  • 5,342
  • 1
  • 23
  • 39
  • The activity_main.xml is present and integrated, it is in the layout folder in it. And the mainActivity is declared in the manifest. – Berat Rex Haj Sep 21 '17 at 00:56
  • Can you try what I mentioned? Comment out everything in main activity XML other then the parent XML relative layout or whatever your parent element is. Then comment out the showstartfragment See if it runs fine without the XML content. Then add back in the main activity content and run again, if crashes your issue is one of the children in main and you just have to one by one try until you find it. If it runs then it maybe a nested fragment that you are trying to put in place and we can troubleshoot that next. Let me know what you find out from this if you would like further assistance. – Sam Sep 21 '17 at 04:59
  • I Try it, annything ok. I debug the app and it crushed at the point: public void fillTextView(int id, String text){ TextView tv = (TextView) findViewById(id); tv.setText(text); } – Berat Rex Haj Sep 21 '17 at 20:27
  • ok so now let's see what called it. As you call it 3 times in a row. Which id breaks the fill method? Also it appears you are starting a thread to do the countdown stuff and then trying to touch UI elements. You will need to make sure you are using a main Handler if you are going to do this. mHandler = new Handler(Looper.getMainLooper()) and use that to post your runnable if you want it on the main thread to touch the UI elements – Sam Sep 21 '17 at 20:33
  • In update() the first filtTextView fro points start, the Integer is "0", than tha fillTextView is called, than i got the id 2131296266 and for tv.setText(text) i got "0" than the app brake down... so he dosen´t jump to fillTextView(R.id.round....); – Berat Rex Haj Sep 21 '17 at 20:44
  • Ok can you try adding this to your update code: MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { fillTextView lines here and see if it is better } }); – Sam Sep 21 '17 at 20:47
  • The same it just start the first line of fillTextView than goes to fillTextView(...) and brake after tv.setText(text); – Berat Rex Haj Sep 21 '17 at 20:50
  • U got a other idea what i can be, maybe the TextView in the layout XML does the truble??? – Berat Rex Haj Sep 21 '17 at 21:15
  • I'm sure we could fix it in a matter of minutes. Do you have TeamViewer? – Sam Sep 21 '17 at 21:26
  • ok give me a minute. I'm on a call with Gradle they are updating me with all latest 4.0 changes. I'll join you in a minute – Sam Sep 21 '17 at 21:41
  • looks like we lost connection – Sam Sep 21 '17 at 21:46
0

You can use this,

<item name="frog_id" type="id"/>

This give you unique value. You add this in your ids.xml. and change your code

...
frog.setId(R.id.frog_id);
...
else if(view.getId()==R.id.frog_id)

Try this

amuyu
  • 236
  • 1
  • 2
  • 9
0

This is related to setting the view id. You can't set the id with the following:

private static final int FROG_ID = 212121;

...
frog.setId(FROG_ID);

You need to define an id in res/values/ids.xml:

<?xml version="1.0" encoding="utf-8"?>

<resources>   
   <item name="your_view_id" type="id"/>     
</resources>

But this will against the purpose of creating a dynamic view.

Instead, you can use View.generateViewId for the id instead. But please remember that this method only work from API version 17. Here the excerpt:

int generateViewId ()

Generate a value suitable for use in setId(int). This value will not collide with ID values generated at build time by aapt for R.id.

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96