2013-02-25 3 views
1

내 UI를 최신 상태로 유지하기 위해 Observer Pattern을 읽었지만 여전히 작동하지 않습니다. Observer가 내 UI이고 내 애완 동물을 감시한다는 전까지는 이해할 수 있습니다. 어떤 변수가 있으면 update(); 분은 Log.d조차도 아무것도하지 않습니다.Observables Observables 이슈를 구현 함

관찰자/MainActivity

package com.grim.droidchi; 

import java.util.Observable; 
import java.util.Observer; 

import android.app.Activity; 
import android.app.AlarmManager; 
import android.app.PendingIntent; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.webkit.WebSettings.LayoutAlgorithm; 
import android.webkit.WebView; 
import android.widget.Button; 
import android.widget.TextView; 
import android.widget.Toast; 

public class MainActivity extends Activity implements Observer, OnClickListener { 
    private static final String TAG = "VPET"; 
    private static final String APP_PREFS = "VPET"; 
    private static final int REQUEST_CODE = 1; 

    TextView happiness_display, health_display, hunger_display, level_display; 
    Button PunchPet, UpdateHunger; 
    public static Pet pet = new Renamon(); 

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

     WebView myWebView = (WebView) findViewById(R.id.pet_display); 
     myWebView.loadUrl("file:///android_asset/renamon.gif"); 
     myWebView.setInitialScale(10000); 
     myWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); 


     PunchPet = (Button) findViewById(R.id.PunchPet); 
     UpdateHunger = (Button) findViewById(R.id.UpdateHunger); 
     final TextView hunger_display = (TextView) findViewById(R.id.hunger_display); 
     TextView happiness_display = (TextView) findViewById(R.id.happiness_display); 
     TextView level_display = (TextView) findViewById(R.id.level_display); 
     TextView health_display = (TextView) findViewById(R.id.health_display); 

     hunger_display.setText(Integer.toString(pet.getHunger())); 
     health_display.setText(Integer.toString(pet.getHP())); 
     level_display.setText(Integer.toString(pet.getLVL())); 
     happiness_display.setText(Integer.toString(pet.getHappy())); 


     Intent intent = new Intent(this, Gameloop.class); 
     PendingIntent pendingIntent = PendingIntent.getBroadcast(
       getBaseContext(), REQUEST_CODE, intent, 0); 

     AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); 
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 
       System.currentTimeMillis() + (5 * 1000), 1800000, pendingIntent); 
     // 1800000 ms = 30 mins 

     pet.feed(); 
     pet.addObserver(this); 
     pet.notifyObservers(pet); 


    } 

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

    @Override 
    protected void onPause() { 


     super.onPause(); 
    } 

    @Override 
    public void update(Observable o, Object data) { 
     Toast.makeText(getApplicationContext(), "soemthing has changed", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    public void onClick(View v) { 
     if (v == PunchPet) { 
      pet.setLVL(50); 
      pet.notifyObservers(pet); 
      Log.d(TAG, "PUNCHPET" + pet.getHP()); 

    }else { 

    } 



    } 

} 

관찰 가능한/애완 동물 나는이를 요청했습니다하지만 당신도 알다시피, 그것은 그들이 어쩌면 할 수 있지만 잘되지 않는 (두 개의 답을 얻었다 예

package com.grim.droidchi; 

import java.util.Observable; 


import android.util.Log; 

public class Pet extends Observable implements PetInterface { 

    private static final String TAG = "VPET"; 
    private int Health = 100; 

    private int Happiness = 10; 
    private int Level = 1; 
    private int Hunger = 0; 
    private int Exp = 0; 
    private String Name; 
    private Boolean isAlive = true; 
    private Boolean isSick = false; 

    public void setisAlive(boolean answer) { 
     this.isAlive = answer; 
    } 

    public void setisSick(boolean answer) { 
     this.isAlive = answer; 
    } 

    public void setHP(int hp) { 
     this.Health = hp; 
     notifyObservers(hp); 
    } 

    public void setLVL(int lvl) { 
     this.Level = lvl; 
     notifyObservers(lvl); 
    } 

    public void setXP(int xp) { 
     this.Exp = xp; 
     notifyObservers(xp); 
    } 

    public void setHunger(int hunger) { 
     this.Hunger = hunger; 
     notifyObservers(hunger); 
    } 

    public void setHappy(int happy) { 
     this.Happiness = happy; 
     notifyObservers(happy); 
    } 

    public int getHP() { 

     return Health; 
    } 

    public int getLVL() { 

     return Level; 
    } 

    public int getXP() { 

     return Exp; 
    } 

    public int getHunger() { 

     return Hunger; 
    } 

    public int getHappy() { 

     return Happiness; 
    } 

    public boolean isAlive() { 
     return isAlive; 

    } 

    public boolean isSick() { 
     return isSick; 

    } 

    @Override 
    public void sleep() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void clean() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void feed() { 
     Log.d(TAG, "FEEDING FROM INTERFACE THING"); 

    } 

    @Override 
    public void passtime() { 

    } 

} 

도와주세요) 내가 그것을 삭제할 수 있다면,이 목록을 아래로 너무 멀리 떨어거야 이제 더 이상받을 수 없습니다 나는 것

로그 캣

02-25 22:51:50.381: E/AndroidRuntime(12026): FATAL EXCEPTION: main 
02-25 22:51:50.381: E/AndroidRuntime(12026): java.lang.NullPointerException 
02-25 22:51:50.381: E/AndroidRuntime(12026): at com.grim.droidchi.MainActivity.update(MainActivity.java:93) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at java.util.Observable.notifyObservers(Observable.java:138) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at com.grim.droidchi.Pet.setHP(Pet.java:33) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at com.grim.droidchi.MainActivity$1.onClick(MainActivity.java:47) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at android.view.View.performClick(View.java:4202) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at android.view.View$PerformClick.run(View.java:17340) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at android.os.Handler.handleCallback(Handler.java:725) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at android.os.Handler.dispatchMessage(Handler.java:92) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at android.os.Looper.loop(Looper.java:137) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at android.app.ActivityThread.main(ActivityThread.java:5191) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at java.lang.reflect.Method.invokeNative(Native Method) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at java.lang.reflect.Method.invoke(Method.java:511) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) 
02-25 22:51:50.381: E/AndroidRuntime(12026): at dalvik.system.NativeStart.main(Native Method) 
+0

예를 들어, 'notifyObservers (굶주림)'. 이 방법은 어디에 있습니까? –

+0

왜'Observable' 메소드를 모두 오버라이드하고'Observers'를 스스로 추적하려고합니까? –

+0

죄송합니다 무슨 말씀인지 모르겠습니까? 변수를위한 메소드가 있어야합니까? 나는 생각이 바뀌었다면 (뭔가 상관 없다) Observable은 Observer가 Observer가 업데이트를 실행하고 textviews에 새로운 값을 새로 고칠 수 있음을 알게했다. – Pheonix2105

답변

2

Observable에서 상속 받으면 클래스는 모든 기능을 상속받습니다. 자신의 기능을 추가하지 않는 한 자신의 메서드를 재정의하거나 자신의 집합을 Observers으로 유지할 필요가 없습니다. Bailey S에 명시된대로 세터 메소드에서 notifyOservers()으로 전화하기 전에 setChanged()으로 전화하십시오.

Observable 클래스에서 재정의 한 메소드를 모두 삭제 해보세요. 또한 notifyObservers(object)에 전화 할 때마다 나중에 clearChanged()으로 전화하십시오.

+0

조언을 구한 후에 다시 편집했습니다. 거의 읽은 적이 있거나 본 모든 일은 나 자신을 구현해야한다고 말했지만, 여전히 작동하지 않지만보다 의미를 갖기 시작했습니다. 이제는 업데이트 방법이 아무것도 표시되지 않습니다. 내 로그에 올라와. – Pheonix2105

+0

명확히하기 위해 나는 아직도 이것을 이해하지 못했습니다. (도움은 여전히 ​​좋지만, 도망 쳤을 때 당신을 비난하지 않을 것입니다.)하지만 당신이 가장 도움이되고 적대적 이었기 때문에 당신의 대답을 받아 들였습니다. 진심으로 감사드립니다. – Pheonix2105

+0

Observer-Observable이 올바르게 설정 되었기 때문에'PunchPet'보기와'onClick' 방법과 관련이있을 것입니다. –

2

notifyObservers()을 오버라이드했지만 notifyObservers(java.lang.Object)을 오버라이드하지 않는 것이 문제입니다. 당신은 후자를 부르고 있지만, 당신은 그것을 정의하지 않았습니다.

@Override 
    public void notifyObservers(Object o) { 
     observers.notify(o); 
     super.notifyObservers(o); 
    } 

또한 내부적으로 값을 변경할 수도 있지만 관찰자는 알 수 없습니다. 애완 동물 (Observable)에서 setChanged()으로 전화하면 문제를 해결할 수 있습니다.

+0

실제로 왜 그가 그것을 무시할 것인지 확실하지 않습니다. 나는 보거나 생각하지도 않았다. –

1

을 호출하기 전에는 notifyObservers() 메서드가 아무런 문제가 없습니다. 이는 항상 관찰자에게 알려야하는 것처럼 보일 수 있기 때문에 직관적이지는 않지만 그렇지 않습니다. notifyObervers()도 변경된 플래그를 지우므로 clearChagned() 메서드를 사용할 필요가 없습니다. getter 및 setter이 같은 코드를 사용

또한
public void setHP(int hp) { 
    this.Health = hp; 
    setChanged(); 
    notifyObservers(hp); 
} 

Observable에 메소드를 오버라이드 (override)하지 않는, 당신은 단지 인터페이스`관찰자의 방법을 구현 해야합니다.

귀하의 update() 방법은 어떤 조치를 취해야합니다. 다음은 아주 간단한 예제 코드입니다. 개체와 데이터는 이미 어떤 개체인지 알기 때문에 무시됩니다. 모든 필드를 업데이트하기 만하면됩니다. Observable 개체와 데이터는 무시됩니다.

@Override 
public void update(Observable o, Object data) { 
    Toast.makeText(getApplicationContext(), "soemthing has changed",Toast.LENGTH_LONG).show(); 

    //Update the GUI fields with values from the local pet object. 
    hunger_display.setText(Integer.toString(pet.getHunger())); 
    health_display.setText(Integer.toString(pet.getHP())); 
    level_display.setText(Integer.toString(pet.getLVL())); 
    happiness_display.setText(Integer.toString(pet.getHappy())); 

} 

onCreate()에서 인스턴스 변수를 올바르게 초기화해야합니다. 그들은 새로운 변수를 만드는 대신에 당신이 실제로 설정하려는 사람들을 설정하고 있기 때문에 즉

onCreate() { 
    ... 

    hunger_display = (TextView) findViewById(R.id.hunger_display); 
    happiness_display = (TextView) findViewById(R.id.happiness_display); 
    level_display = (TextView) findViewById(R.id.level_display); 
    health_display = (TextView) findViewById(R.id.health_display); 

    ... 
} 

, 당신은 TextView 선언을 제거해야합니다.

+0

안녕 베일리는 정말 고맙게 받아 들여 주셔서 감사합니다. setChanged()를 포함하여 코드를 다시 변경했습니다. setter에 (게터를해야합니까? 그냥 값을 검색하고 변경하지 않아야하는 것처럼 보이지 않습니까?) 익명의 클래스를 사용하여 버튼에 적용했지만 현재 작동하지만 값은 업데이트되지 않습니다. ? 예를 들어, 나는 pet.setLVL (50); 버튼의 onclick에 업데이트 방법이 실행 중이지만 값이 변경되지 않는다고 알려줍니다. – Pheonix2105

+0

get 메소드에서 관찰자에게 통지 할 이유가 없으며 실제로 getter가 자주 호출되면 성능에 끔찍한 영향을 미칩니다. 'update()'메쏘드에서 아무것도 갱신되지 않는다. 터미널에 출력하는 것 외에 아무것도 넣지 않았기 때문이다. 'update()'에서 실제로 뭔가를 할 필요가있다. Observer/Observable은 매우 간단하며 "마술"을하지 않습니다. 나는 내 대답에 샘플'update()'를 추가 할 것이다. –

+0

"\t hunger_display.setText (Integer.toString (pet.getHunger()));" 내 업데이 트에 있지만 그것은 그것을 제거하기 때문에 응용 프로그램이 충돌하게됩니다. 정확하게 nullpointer 예외를 슬로우합니다. – Pheonix2105

관련 문제