2014-02-15 4 views
0

Я только начал изучать андроид. Следующий код показывает мою первую попытку.объяснение почему я не могу установить эти переменные глобальные

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; 

/* ** * * * Я хочу, чтобы объявить его здесь, но приложение падает, если я сделать

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); 
     } 

    } 

} 

Мой вопрос, почему я должен объявить

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

внутри функция. Почему я не могу объявить его на уровне класса. Приложение падает, если я объявляю его на уровне класса. Каждый раз, когда функция toggleGui называется новым объектом этих двух классов, и это будет неэффективно, я думаю, но я могу ошибаться. Может ли кто-нибудь дать мне хорошее объяснение. Благодарю.

+2

Что вы подразумеваете под «уровнем класса»? Вы можете объявить их там, где хотите, после того как явно вызывается setContentView. – Enrichman

+1

Вы можете объявить их как переменные экземпляра, то есть члены класса, но вы не можете инициализировать 'Drawable' перед' onCreate() 'и' View 'перед' setContentView() ', поскольку ресурсы приложения ограничены' Activity' из 'onCreate() '... –

ответ

2

Объявление в действии не является проблемой.

findViewById для вашего ImageView следует вызывать после настройки вашего содержимого. (макет для этой деятельности).

В противном случае, следующее должно работать:

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)
Для findViewById:
http://developer.android.com/reference/android/app/Activity.html#findViewById(int)

0

обычно вы должны создавать изменяемые переменные Whithin области, в которой они используются - это ООП инкапсуляция/свободная связь/концепция высокой когезии, и я предлагаю следовать ей по многим причинам)

Вы можете определить их на уровне класса, который, как я полагаю, просто убедитесь, что они были инициализированы правильно, прежде чем обращаться к ним - приложение, скорее всего, связано с тем, что вы пытаетесь вызвать toggleGUI перед определением изображения.

С уважением,

Alex.

0

Объявляет Youre уровня переменного класса следующего

ImageView imageView; 

и инициализировать его внутри метода OnCreate после setcontentview (R.layout.your_layout);

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

не инициализируйте его на toggleGUI(). потому что он никогда не вызывает внутри onCreate().

инициализируйте все элементы пользовательского интерфейса внутри метода oncreate().

Смежные вопросы