ntstha
ntstha

Reputation: 1173

explanation why i cannot set these variable global

I have just started learning android. Following code shows my first attempt.

package com.example.silentphone;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private AudioManager audioManager;
    private boolean mPhoneIsSilent;

/******I want to declare it here but the app crashes if i do

    ImageView imageView = (ImageView) findViewById(R.id.ringer_icon);
        Drawable newPhoneIcon;

*******************************/

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

        audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        checkPhoneStatus();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public void onClick(View view) {
        Button toggleButton = (Button) findViewById(R.id.toggleBtn);
        if (mPhoneIsSilent) {
            System.out.println("Phone Silent");

            // now put the phone in ringer mode

            audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);

            mPhoneIsSilent = false;

            toggleGUI();
        } else {
            System.out.println("Phone active");

            // now put the phone in silent mode

            audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);

            mPhoneIsSilent = true;

            toggleGUI();
        }

    }

    public void checkPhoneStatus() {
        int ringerMode = audioManager.getRingerMode();
        if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
            // means the phone is silent
            mPhoneIsSilent = true;

        } else {
            mPhoneIsSilent = false;

        }
    }

    public void toggleGUI() {

  /******These two variables need to be declared here.Why cant i declare it at class level.If i declare it at class level the app crashes.s****************************/
        ImageView imageView = (ImageView) findViewById(R.id.ringer_icon);
        Drawable newPhoneIcon;
  /******************************************************************************/

        if (mPhoneIsSilent) {
            // means the phone is silent so show phone silent image
            newPhoneIcon = getResources().getDrawable(R.drawable.speaker_off);
            imageView.setImageDrawable(newPhoneIcon);
        } else {
            newPhoneIcon = getResources().getDrawable(R.drawable.phone_on);
            imageView.setImageDrawable(newPhoneIcon);
        }

    }

}

My question is why i need to declare

ImageView imageView = (ImageView) findViewById(R.id.ringer_icon);
        Drawable newPhoneIcon;

within the function. Why cant i declare it in class level. App crashes if i declare it in class-level. Every time function toggleGui is called a new object of those two classes is made and that will be ineffective i guess but i may be wrong. Can someone provide me with a good explanation. Thanks.

Upvotes: 0

Views: 278

Answers (3)

user1688181
user1688181

Reputation: 494

Declare youre variable class level as follows

ImageView imageView;

and initialize it inside oncreate method after setcontentview(R.layout.your_layout);

imageView = (ImageView) findViewById(R.id.ringer_icon);

do not initialize it on toggleGUI() method. because it is never call inside the onCreate().

initialize your all UI elements inside oncreate() method.

Upvotes: 0

Alex Evseenko
Alex Evseenko

Reputation: 141

generally you should create any mutable variables whithin the scope in which they are used -- it's OOP encapsulation/loose coupling/high cohesion concept and I suggest to follow it for many reasons )

You can define them in class level I believe, just make sure they are initialized properly before access them -- the app craches probably because you try to call toggleGUI before imageView defined.

Regards,

Alex.

Upvotes: 0

Pararth
Pararth

Reputation: 8134

The declaration in Activity is not a problem.

The findViewById for your ImageView should be called after setting your content view. (layout for the activity).

Otherwise, the following should work:

 public class MainActivity extends Activity {

        private AudioManager audioManager;
        private boolean mPhoneIsSilent;
        //declaring these here is not a problem
        ImageView imageView; 
        Drawable newPhoneIcon;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //when you map the imageView, it should be after the setContentView so your activity identifies exactly what to map - for id and component -in your layout
            imageView = (ImageView) findViewById(R.id.ringer_icon);

            audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
            checkPhoneStatus();
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }

        public void onClick(View view) {
            Button toggleButton = (Button) findViewById(R.id.toggleBtn);
            if (mPhoneIsSilent) {
                System.out.println("Phone Silent");

                // now put the phone in ringer mode

                audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);

                mPhoneIsSilent = false;

                toggleGUI();
            } else {
                System.out.println("Phone active");

                // now put the phone in silent mode

                audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);

                mPhoneIsSilent = true;

                toggleGUI();
            }

        }

        public void checkPhoneStatus() {
            int ringerMode = audioManager.getRingerMode();
            if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
                // means the phone is silent
                mPhoneIsSilent = true;

            } else {
                mPhoneIsSilent = false;

            }
        }

        public void toggleGUI() {

            if (mPhoneIsSilent) {
                // means the phone is silent so show phone silent image
                newPhoneIcon = getResources().getDrawable(R.drawable.speaker_off);
                imageView.setImageDrawable(newPhoneIcon);
            } else {
                newPhoneIcon = getResources().getDrawable(R.drawable.phone_on);
                imageView.setImageDrawable(newPhoneIcon);
            }

        }

    }

http://developer.android.com/reference/android/app/Activity.html#setContentView(int)
For findViewById:
http://developer.android.com/reference/android/app/Activity.html#findViewById(int)

Upvotes: 2

Related Questions