Nybörjarfråga...

Discussion in 'Frågor, support och diskussion' started by Nepsir, Dec 29, 2009.

  1. Nepsir

    Nepsir Kid Droid Medlem

    Joined:
    Jul 11, 2009
    Messages:
    74
    Likes Received:
    0

    MINA ENHETER

    Jag har lite smått börjat pilla med lite programmering för android men har stött på lite problem. Huvudorsaken till problemen är för att jag är för dålig på java....

    Jag har i kodstycket nedan skapat variabeln tv som jag sedan längre ner i koden försöker anropa men den hittas då inte. Jag antar att det är ett enkelt problem men jag förstår mig inte riktigt på det...

    PHP:
    package se.danielsturesson.shbprivat;

    import java.io.BufferedInputStream;
    import java.io.InputStream;
    import java.net.URL;
    import java.net.URLConnection;

    import org.apache.http.util.ByteArrayBuffer;

    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.widget.TextView;
    import android.widget.Toast

    public class 
    kontrollkodActivity extends Activity {  
         private 
    String html "Fetching...";  
         private 
    Handler mHandler
       
         public 
    void onCreate(Bundle savedInstanceState) {  
             
    super.onCreate(savedInstanceState);  
             
    setContentView(R.layout.meny);  
             
    mHandler = new Handler();  
             
    checkUpdate.start();
             
    //Nedanstående variabel hittas inte längst ner i kodstycket
             
    TextView tv = new TextView(this);
         }  
       
        private 
    Thread checkUpdate = new Thread() {  
             public 
    void run() {  
                 try {  
                     
    URL updateURL = new URL("http://www.anddev.org/images/tut/basic/getdatafromtheweb/loadme.txt");  
                     
    URLConnection conn updateURL.openConnection();  
                     
    InputStream is conn.getInputStream();  
                     
    BufferedInputStream bis = new BufferedInputStream(is);  
                     
    ByteArrayBuffer baf = new ByteArrayBuffer(50);  
       
                     
    int current 0;  
                     while((
    current bis.read()) != -1){  
                         
    baf.append((byte)current);  
                     }  
       
                     
    /* Convert the Bytes read to a String. */  
                     
    html = new String(baf.toByteArray());  
                     
    mHandler.post(showUpdate);  
                 } catch (
    Exception e) {  
                 }  
                 
             }  
         };  
       
         private 
    Runnable showUpdate = new Runnable(){ 
              public 
    void run(){  
                 
    //Variabeln tv som skapades i "public void onCreate(Bundle savedInstanceState)" hittas inte här.  
                 
    tv.setText(html);
                 
    this.setText(tv);
             }
         };}
     
  2. svanlund

    svanlund Youth Droid Medlem

    Joined:
    Jun 5, 2009
    Messages:
    223
    Likes Received:
    0

    MINA ENHETER

    Code:
    private String html = "Fetching...";  
    private Handler mHandler;
    private TextView tv = new TextView(this);
    Genom att flytta upp tv dit så har du tillgång till den i hela klassen. I din kod så är tv lokal och finns bara i just onCreate.
     
  3. yrara

    yrara Teen Droid Medlem

    Joined:
    Sep 30, 2009
    Messages:
    428
    Likes Received:
    8

    MINA ENHETER

    Beroende på var i koden du deklarerar en variabel, så påverkar du dess scope, eller dess livslängd. En variabel existerar bara inom ett visst scope, som kan vara olika stort. Skapar du en variabel, "tv", i onCreate, så kan du skapa en helt annan variabel med precis samma namn i en annan metod, och de kan existera oberoende av varandra. Det här är helt önskvärt, för att du ska kunna förlita dig på att koden du skriver inte påverkas helt och hållet av annan kod som råkar köras samtidigt.

    Ifall du däremot vill se till att en variabel ska vara tillgänglig i en helt annan metod, och du inte har möjlighet att skicka variabeln som en parameter till den metoden, så kan du ge den ett större scope, genom att deklarera den utanför metoden. Dina variabler "html" och "mHandler" är exempel på variabler som är deklarerade utanför metoden, och har hela klassen "kontrollkodActivity" som sitt scope. Ifall du deklarerar "tv" där, så kommer du att kunna nå den från din runnable också.

    Förresten: Tja daniel, det var sjukt längesen /david hedlund
     
  4. roxer2b

    roxer2b Teen Droid Medlem

    Joined:
    Sep 8, 2009
    Messages:
    481
    Likes Received:
    0

    MINA ENHETER

    Det går också att deklararera en variabel och instansiera den i olika scope och ha tillgång till instansen i andra scope än där du skapade den.

    Så du kan deklarera tv som en medlemsvariabel på klassen (Inte i en funktion) men instansiera den i onCreate() och ha tillgång till den längre ner.
    Huruvida man nu *ska* göra så är en annan femma, och diskuteras lite fram och tillbaks i programmeringskretsar. Personligen tror jag nog på RAAI, som är en tumregel som säger att man ska instansiera variabler vid deklareringen. (Annars kan man försöka använda den när den inte är instansierad, vilket gör antingen OSet eller i javas fall, JVMen ledsen)
     
  5. yrara

    yrara Teen Droid Medlem

    Joined:
    Sep 30, 2009
    Messages:
    428
    Likes Received:
    8

    MINA ENHETER

    Personligen förespråkar jag inte att instansiera alla variabler vid deklarering. Det finns massvis av situationer där man vet att man alltid kommer att ha ett värde när man accessar variabeln för första gången. Ex:

    Code:
    XmlDocument doc;
    
    try {
        doc = XmlDocument.Parse(xmlString);
    } catch(Exception ex) {
        Log(ex);
        throw;
    }
    
    XmlNode root = doc.DocumentElement;
    Antingen så tilldelas ett nytt värde, eller så bryts flödet (throw). Skulle vi tilldela ett värde vid deklareringen, så skulle det vara ett som vi vet aldrig kommer att användas. En sådan tilldelning skulle kännas mycket överflödig.

    Vad gäller medlemsvariabler på klasser har vi dock ett beroende på ett speciellt kod-flöde, som det inte finns någon motsvarighet till i ovanstående exempel. Beroende på var vi tilldelar, och var vi läser en variabel, kan vi kanske inte veta att den alltid kommer att ha ett värde. När sådana beroenden på flöden uppstår, är det alltid värt att fråga sig om inte ett större fel har inträffat i hur flödet är upplagt. I Nepsirs kod skulle jag till exempel hellre deklarera tv i run() (och skicka in kontrollkodActivity.this istället för this) med tanke på att den som det ser ut just nu inte används någon annanstans.

    Hursomhelst; i de fall där ett sådant beroende på flöde faktiskt är motiverat, skulle jag fortfarande inte tilldela värde till en medlemsvariabel direkt vid deklarationen. Dock av en helt annan anledning: Jag vill inte ha en massa logik där. För att vara säker på att de alltid har ett värde (om det nu är vad jag vill) skulle jag istället se till att tilldela dessa värden i konstruktorn.

    Men för att återgå till scope, så kanske det här är utanför scope för en nybörjarfråga...
     
    Last edited: Dec 29, 2009
  6. Nepsir

    Nepsir Kid Droid Medlem

    Joined:
    Jul 11, 2009
    Messages:
    74
    Likes Received:
    0

    MINA ENHETER

    När man får svar som dessa kan man inte annat än tacka för så ingående svar, nu börjar jag förstå lite bättre vad jag sysslar med.

    Skall testa det så fort jag kommer hem från jobbet.

    Igen, TACK!!

    Edit: David!! Inte igår inte.
     
    Last edited: Dec 29, 2009