Organisera koden

Diskussion i 'Frågor, support och diskussion' startad av vg132, 9 nov 2010.

  1. vg132

    vg132 Infant Droid Medlem

    Blev medlem:
    6 feb 2010
    Inlägg:
    6
    Mottagna gillanden:
    0

    MINA ENHETER

    Hej!

    Jag lekar lite i Android på fritiden men jobbar på dagarna med C# och webben där nästan varje liten del av sidan bryts ut till egna små units som innehåller sin egna logik osv, många små delar. I mitt "stora" Android projekt är jag nu uppe i 700 rader kod i min main activity och har brutit ut allt som jag kan (med mina begränsade kunskaper) men tycker fortfarande att det är på tok för mycket och oöverskådligt (saknar C# regions ;)) och undrar nu hur man gör i Android för att dela upp koden lite bättre och om det går.
    Jag har t.ex. tre tabbar i appen och tycker att det skulle vara grymt om jag på något sätt kunde lägga koden för varje tab i en egen fil.
    Hur skulle man kunna gör det i Android? Eller bygger man helt enkelt inte på det sättet i Android?

    /Viktor
     
  2. henca

    henca Senior Droid Medlem

    Blev medlem:
    30 dec 2009
    Inlägg:
    1 337
    Mottagna gillanden:
    213

    MINA ENHETER

    Naturligtvis kan du bryta ut funktioner som du lägger i andra filer. Dessa funktioner anropar du sedan på följande vis:

    filnamn.funktionsnamn(argument);

    m v h Henrik
     
  3. afzkl

    afzkl Youth Droid Medlem

    Blev medlem:
    27 aug 2009
    Inlägg:
    184
    Mottagna gillanden:
    6

    MINA ENHETER

    Hejsan

    Just när det gäller TabActivtys så kan du faktiskt dela upp dem i en Activity för varje tab. Det finns två sätt att använda en TabActivity, det ena är att ha allt i en Activity och det andra är som jag nämnde att dela upp det. Jag använder båda sätten i mitt projekt har jag för mig och det finns vissa för och nackdelar.

    Här är en guide på att dela upp det tror jag:
    http://blog.henriklarsentoft.com/2010/07/android-tabactivity-nested-activities/

    Nackdelen är att så vitt jag vet kan du inte kommunicera mellan de olika tabbarna eller med din main TabActivity på något enkelt vis vilket kan skapa bekymmer i vissa situationer.

    När det gäller att organisera i enskilda activity klassar har jag tyvärr inte många tips dig då jag själv brottas med samma bekymmer. Det springer ofta iväg på upp emot 2-3 tusen rader och jag vet inte var jag ska göra hän allt. När hela projektet hamnat på långt över det tiodubbla så kan det börja bli lite rörigt.

    Vi har haft det upp på forumet och diskuterat det tidigare och tipsen ar väll varit att försöka ha så lite kod så möjlig i activty klasserna och flytta ut allt som arbetar i det tysta och inte har med gränssnittet att göra. Men det är svårt och det kan bli rörigt det med. Man kanske ska skriva mindre kod helt enkelt.;)

    Själv har jag väll inga bekymmer då jag är välbekant med den kod jag skrivit med skulle någon annan komma och titta på det så kanske de skulle få det något värre, jag vet inte. Allt ligger uppdelat i undermappar och är ganska organiserat men som sagt, många klasser ligger lång över 1000 rader.
     
  4. PatrikS

    PatrikS Senior Droid Medlem

    Blev medlem:
    29 jun 2009
    Inlägg:
    1 123
    Mottagna gillanden:
    65

    MINA ENHETER

    Det du kan göra är att försöka se på andra publika projekt och se hur de gör.
    Jobba mycket med motsvarigheten till C# namespaces dvs paket.

    C# regions är tycker jag bra ibland men för det mesta meningslöst, dock inte lika mycket till fördärvelse som partial klasser. ;)

    Låt oss säga att din activity använder en klass för att komma åt en REST-service eller WS så skriver du givetvis en egen klass för det.

    I mitt exempel så har jag

    se.utvecklarnamn.projekt.ui.MainActivity.java

    och

    se.utvecklarnamn.project.net.ws
    se.utvecklarnamn.project.net.rest

    eventuella hjälpklasser kanske

    se.utvecklarnamn.project.net.helpers eller inom andra paket

    databashantering

    se.utvecklarnamn.project.dao eller
    se.utvecklarnamn.project.repository

    man bör undvika interface för att snygga upp då det faktiskt medför en försämring av prestanda då android inte kan "inline":a virtual calls.

    Läs mer här :

    http://developer.android.com/guide/practices/design/performance.html

    (Jag har faktiskt använt interface här och där men då är det medvetet med prestandaförlust i åtanke)
     
  5. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Det låter lite som en tankevurpa. Java är objektorienterat, och i objektorienterade språk brukar man säga att en klass skall göra en sak, och endast en sak. Därför tenderar klasser ofta till att bli många men små. Har kan mer än 200-300 rader i en klass så bör man fundera på om man inte kan bryta upp sitt problem i delproblem. Det är inte alltid det går, men klasser som är på flera tusen rader böra vara relativt ovanligt.
     
  6. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Om jag förstår artikeln rätt så är det endast sant i Androidversioner som saknar JIT dvs alla före Android 2.2
     
  7. PatrikS

    PatrikS Senior Droid Medlem

    Blev medlem:
    29 jun 2009
    Inlägg:
    1 123
    Mottagna gillanden:
    65

    MINA ENHETER

    Ja, artikeln jag hänvisade till är uppdaterad efter att 2.2 kom så mycket gäller fortfarande.

    Fortfarande så är många enheter utan möjlighet till JIT så att frångå gamla regler som interfaces, encapsulation, osv kan ändå ge prestandavinster (och minne(?)) där det är vikitigt.
    Personligen använder jag gärna ett ordentligt IoC-ramverk exv. spring och nyttjar aop, men jag skulle inte drömma om att använda det i androidutveckling (än).

    Ett annat exempel är enums som jag gärna använder, men i android så klarar man sig bra med "bara" statiska final ints.

    Jag har brutit ut så mycket kod jag kan ur mina activitys så det är bara kod som
    hanterar gui där men jag antar att privata klasser ändå är ok i sådana här fall t.ex.
    även om det blir rörigt.
     
  8. vg132

    vg132 Infant Droid Medlem

    Blev medlem:
    6 feb 2010
    Inlägg:
    6
    Mottagna gillanden:
    0

    MINA ENHETER

    Tack för svaren får läsa igenom det mer noga när jag kommer hem. Kanske inte var helt tydlig i första inlägget men det är främst just GUI delarna som ligger i Activity klasserna som jag tycker blir groteskt stora och oöverskådliga. DB, GPS, NET osv kod ligger redan i egna paket och klasser. Låter dock intressant om man kan flytta in varje tab till en egen activity då borde det bli lite mer överskådligt.

    /Viktor
     
  9. PatrikS

    PatrikS Senior Droid Medlem

    Blev medlem:
    29 jun 2009
    Inlägg:
    1 123
    Mottagna gillanden:
    65

    MINA ENHETER

    glöm inte att du kan använda

    android: onClick direkt i xml-arket för att spara lite "boiler-plate" i din activity också.

    koden som tar hand om eventet i din activity blir då följande :

    public void button1Click(View v){
    //do stuff here
    }

    då kan du spara iaf ett tiotal rader kod kanske :D

    läs mer här:

    http://developer.android.com/guide/topics/ui/ui-events.html
     
  10. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Det jag försökte säga var att du även kan delegera och lägga gui-logik i andra klasser. Allt måste ju inte ligga i samma klass.
     
  11. afzkl

    afzkl Youth Droid Medlem

    Blev medlem:
    27 aug 2009
    Inlägg:
    184
    Mottagna gillanden:
    6

    MINA ENHETER

    Ja du, det kanske det är. Dessa riktigt långa klasserna är väll för det mesta activity klasser. Men har även en som endast sköter en tabell i databasen på 1500 rader. Den har en funktion och känns helknäppt om jag skulle dela upp den...

    På tal om långa klasser så ligger TextView klassen i Android SDK:t på över 7000 rader så jag är ju inte värst iaf..;)
     
  12. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    O_o

    Vad gör den tabellen?
     
  13. Zooklubba

    Zooklubba Android Medlem

    Blev medlem:
    10 jul 2010
    Inlägg:
    6 448
    Mottagna gillanden:
    2 199

    MINA ENHETER

    Min updateservice ligger på 3000 rader. Jag är lat, orkar inte massa klasser

    Edit: ofc brukar dela upp det men där har jag delat upp det som funktioner.
     
  14. PatrikS

    PatrikS Senior Droid Medlem

    Blev medlem:
    29 jun 2009
    Inlägg:
    1 123
    Mottagna gillanden:
    65

    MINA ENHETER

    lathet är just en anledning till att jag bryter ner i fler klasser... jag fixar inte att leta i klasser på över 500 rader.
     
  15. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Samma här, dessutom brukar det leda till att man inte göra "copy & paste" lika ofta, och får underhållsproblem.
     
  16. johannilsson

    johannilsson Adult Droid Medlem

    Blev medlem:
    23 jun 2009
    Inlägg:
    577
    Mottagna gillanden:
    8

    MINA ENHETER

    När det kommer till att hantera GUI bitarna går det utmärkt att extenda de widgets som redan finns för att själv göra egna komponenter som är lätta att återanvända. Går även fint att bygga egna widgets. Ett exempel som vi har i Voddler appen är action baren som är högst upp. All funktionalitet för den ligger i en egen komponent som heter ActionBar. Vill vi sedan använda den här widgeten på flera ställen kör vi bara;

    HTML:
    <com.voddler.android.ui.widget.ActionBar
        android:id="@+id/actionbar"
        style="@style/ActionBar"
        />
    
    Man blir av med ganska mycket boilerplate kod genom att gruppera funktionalitet så här.

    Personligen gillar jag inte att köra med android : onClick då jag tycker det gör det betydligt svårare att följa vad det är som händer. Men det är bara en smaksak.
     
  17. Elis

    Elis Kid Droid Medlem

    Blev medlem:
    22 apr 2010
    Inlägg:
    53
    Mottagna gillanden:
    5

    MINA ENHETER

    Jag vill påstå att man INTE ska undvika interface. Med motivationer tagna från samma källa som du länkar till.
    en prestanda förlust på 6% för bara själva metod anropen som antagligen inte ens en tar '1'% själva programprestandan)
    '1'%*6% = 0.06% total prestanda vinst för att inte använda interface. Jag skulle istället föreslå att man la ner tid på att optimera någon annan del av koden.


    Från länken
    "Performance Myths

    Previous versions of this document made various misleading claims. We address some of them here.

    On devices without a JIT, it is true that invoking methods via a variable with an exact type rather than an interface is slightly more efficient. (So, for example, it was cheaper to invoke methods on a HashMap map than a Map map, even though in both cases the map was a HashMap.) It was not the case that this was 2x slower; the actual difference was more like 6% slower. Furthermore, the JIT makes the two effectively indistinguishable.

    On devices without a JIT, caching field accesses is about 20% faster than repeatedly accesssing the field. With a JIT, field access costs about the same as local access, so this isn't a worthwhile optimization unless you feel it makes your code easier to read. (This is true of final, static, and static final fields too.)"

    OCH

    "Consider the performance consequences of your API design decisions. Making a public type mutable may require a lot of needless defensive copying (Item 39). Similarly, using inheritance in a public class where composition would have been appropriate ties the class forever to its superclass, which can place artificial limits on the performance of the subclass (Item 16). As a final example, using an implementation type rather than an interface in an API ties you to a specific implementation, even though faster implementations may be written in the future (Item 52)."
     
  18. PatrikS

    PatrikS Senior Droid Medlem

    Blev medlem:
    29 jun 2009
    Inlägg:
    1 123
    Mottagna gillanden:
    65

    MINA ENHETER

    Jag sa att jag använde interface också, men det beror givetvis på var,
    Jag har sett exempel på folk som skriver ett interface till sin klass som de "kanske" sedan exv. gör en mock på men innerst inne vet att det aldrig kommer ske.

    We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
    —Donald E. Knuth 2

    Jag låter alltid bli meningslös och farlig "optimering" av min kod förrän allt är klart och fungerar.
    Men det är utvecklande att _känna till_ skillnader mellan enheter och den java många av oss normalt utvecklar till med J2EE eller komplexa IoC-ramverk och kanske många andra komponenter såsom ORM-verktyg osv.

    Man kan slösa bort både minne och processor rejält fort i en telefon jämfört med en fet server.
     
  19. PatrikS

    PatrikS Senior Droid Medlem

    Blev medlem:
    29 jun 2009
    Inlägg:
    1 123
    Mottagna gillanden:
    65

    MINA ENHETER

    Detta gör jag också, frågan är bara om man har en länk på denna komponent så måste man ta hänsyn till denna på alla activitys som hänvisar till widgeten?
     
  20. johannilsson

    johannilsson Adult Droid Medlem

    Blev medlem:
    23 jun 2009
    Inlägg:
    577
    Mottagna gillanden:
    8

    MINA ENHETER

    Hmm är inte säker på hur du menar. Just den här komponenten är väldigt generell och har inga hårdkodade intents utan alla sätts vid initieringen liknande;

    Kod:
    ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar);
    actionBar.setTitle(R.string.some_title);
    actionBar.addAction(new Intent(this, OtherActivity.class), R.drawable.actionbar_other);
    
    Men det går bra att bygga skapa och starta andra activities inuti med.