Gå til innhold

Android/Java spørsmål fra .NET programmerer


Anbefalte innlegg

Her flere års erfaring med utvikling til Windows Mobile gjennom Compact Framework. Men sliter med overgangen til Android.

 

I moderne programmeringsspråk. Og da inkluderer jeg C++ er jeg vant med å sende objektreferanser rundt i programmet for bruk eller endring av data. I Android er ikke dette like enkelt.

 

Hvert skjermbilde arver fra Activity. Eneste måten å gi input til en Activity på er gjennom en Intent objekt der en kan legge primitiver som string,int, double bool etc. Dette strider mot alt jeg er opplært til i programmering som innkapsulering etc. Skal jeg redigere et objekt i en dialog sender jeg inn objektet og dialogen endrer det. Objektet kan selvfølgelig inneholde flere underobjekter som skal åpnes i underdialoger osv. Dette er umulig i Android. Ei heller at jeg vil åpne en dialog og ved DialogResult OK så vil jeg f.eks. returnere et nytt objekt av en eller annen type gjennom en property eller noe.

 

Ofte bygger jeg f.eks. opp dialoger og setter providere etc med DI(Dependency Injection) noe som også er umulig her.

Eneste måten jeg på en fornuftig måte kan dele ressurser etc i programmet som skal leve hele "runtimen" til programmet lukkes er gjennom å ha en Singelton "serviceprovider" som kan holde på tjenestene jeg trenger. Dette løser imidlertid ikke mange av problemene jeg beskriver tidligere.

 

Noen som har erfaring fra Android, med tanker hvorfor de har gjort slik de har gjort og hvordan dere evt har løst disse problemstillingene? Har søkt og lest endel rundt om dette og ser mange sliter med de sammme tingene som meg. Men ingen som har et god løsning på hvordan en skal lage større tyngre applikasjoner som ikke er på TicTacToe nivå.

 

I WinMobile har jeg bygget et program på 150.000+ kodelinjer og 150+ dialoger og ser ikke helt hvordan jeg skal kunne bygge tilsvarende kompleksitet på Android.

 

Merk at problemet er ikke Java men Android arkitekturen.

Lenke til kommentar
Videoannonse
Annonse

Jeg har utviklet et par enkle programmer, og som du sier er static resource managers eller singletons tingen du er ute etter.

 

Jeg har ihvertfall i mine android programmer benyttet meg av statiske ressurser. I dag om en use case ikke kan beskrives i en aktivitet ser jeg grundig igjennom om denne usecasen ikke bør endres, men jeg er helt enig at androids måte å håndtere ressursdeling er noe snodig, men tror dette kun er fordi det er annerledes enn hva jeg er vant til.

 

Ellers her finner du jo hva google sier du skal løse det:

 

http://developer.android.com/guide/appendix/faq/framework.html

 

 

Ellers ville jeg råde deg til å legge igjen avanserte patterns og best practices fra andre språk når du kommer over på android. Lag enkel kode; programmet ditt skal ikke utvides i det uendelige, på mitt første program på android gikk jeg i fellen for å prøve mvp, det endte med at jeg måtte bite i gresset å se hva plattformen var ment for. Det endte opp med kun en model (som jeg holdt statisk), og en viewcontroller per aktivitet. Siden du velger et (i dag ihvertfall) primært mobilspråk er det ikke lagt til rette for og egner seg ikke til avanserte programmer med n funksjoner og egenskaper.

Lenke til kommentar

Jeg har utviklet et par enkle programmer, og som du sier er static resource managers eller singletons tingen du er ute etter.

 

Jeg har ihvertfall i mine android programmer benyttet meg av statiske ressurser. I dag om en use case ikke kan beskrives i en aktivitet ser jeg grundig igjennom om denne usecasen ikke bør endres, men jeg er helt enig at androids måte å håndtere ressursdeling er noe snodig, men tror dette kun er fordi det er annerledes enn hva jeg er vant til.

 

Ellers her finner du jo hva google sier du skal løse det:

 

http://developer.android.com/guide/appendix/faq/framework.html

 

 

Ellers ville jeg råde deg til å legge igjen avanserte patterns og best practices fra andre språk når du kommer over på android. Lag enkel kode; programmet ditt skal ikke utvides i det uendelige, på mitt første program på android gikk jeg i fellen for å prøve mvp, det endte med at jeg måtte bite i gresset å se hva plattformen var ment for. Det endte opp med kun en model (som jeg holdt statisk), og en viewcontroller per aktivitet. Siden du velger et (i dag ihvertfall) primært mobilspråk er det ikke lagt til rette for og egner seg ikke til avanserte programmer med n funksjoner og egenskaper.

 

Hei. Takker for utfyllende svar! Var kommet til omtrent samme konklusjonen som deg. Noen som skuffer meg litt.

 

Selv om WinMobile har sine tydelige svakheter føler jeg at Compact CF en svært fleksibel og god plattform. Mens Android er et lite steg tilbake. Moderne og fleksibelt i forhold til å lage små, kjappe enkle programmer på kort tid. Men vanskelig å lage litt halvtunge komplekse programmer.

 

Google har nok gjort dette helt bevisst for å lage små enkle applikasjoner, med lite minnebruk og rask oppstartstid. Dessverre fungerer dette dårlig for meg som forsøker å lage en litt tyngre appliksjon på denne plattformen.

 

Får gjøre det beste ut av det. Strippe ned det som var planen og fjerne endel inngrodde vaner i et MVC hode :)

Lenke til kommentar

Med fare for å bomme litt på det du spør om. Hvis du serializer et objekt kan du sende det med en intent. Og dermed hente det ut i activityen ved å caste det til objektet du ønsker.

 

Hm. Her sett på denne løsningen. Men innebærer ikke det at jeg må deserialisere objektene på activity siden?

 

Dette gjør vel at det er forskjellige "referanser" på objektene? Dvs at jeg ikke kan sende inn et objekt for endring så blir det endret overalt i programmet.

Det andre problemet er at det er relativt mye data i disse objektene. Opp mot 5-10 MB på det værste. Hvis dette skal serialiseres og deserialiseres så ser jeg for meg at dette vil ta ganske lang tid. Når en deserialiser så instansierer jo en i praksis alle objektene på nytt.

Dersom jeg bare hadde sendt inn objektet uendret ville jo det ikke krevd noen ressurser.

 

Mener du at jeg tar feil nå så gjerne gi et hint. Men tolket serialiserings varianten slik at det ikke funket for mitt formål. Men kan hende jeg har misforstått.

 

Foreløpig har jeg landet på et slags servicelocator pattern for å hente data. Men dette løser egentlig ikke helt problemet med å sende objekter mellom dialoger. Har laget et "static aktig pattern" for å passe data men dette er grisete kode jeg er lite fornøyd med.

Lenke til kommentar

Såpass store objekter ja. Brukte det selv på objekter som bare inneholdt en 7-8 primitiver og da gikk det fint. Det er rett som du sier at det da blir opprettet nye objekter hele tiden og for å oppdatere tidligere views må det lastes inn på nytt.

 

Det virker som at det veldig fort blir grisete kode i android. Om det kommer av liten erfaring eller arkitekturen vil jeg ikke si så mye om med det første.

Lenke til kommentar

Du kan eventuelt bruke en SQLite database å lagre ting i mellom activitisene.

 

Skulle til å anbefale det samme. Hvis du i tillegg aksesserer den gjennom en contentProvider vil du ha enkel tilgang til den uansett aktivitet.

 

/Espen

 

Programmet skal ha relativt omfattende med data. Kan typisk laste 5 MB i oppstart. Disse dataene vil bli brukes for å bygge objektstrukturer og indexer etc, inne i programmet som er relativt krevende både med tanke på minne og tidsbruk.

 

Er helt uaktuelt å laste dette opp og ned for hver aktivitet. Fra .NET CF 1.1 har jeg kunne hente inn ressurser i oppstart. Og beholde disse gjnneom "runtimen" til programmet. SqlLite er et supert alternativ for persistent lagring av data. Men håpløst og måtte lagre og hente de for hver gang en bytter dialog. Jeg vil jo selvsagt sende dataene rundt omrking. Blir dataene endret i en dialog sender jeg endrede/slettede/nye data til db laget og endringer blir lagret.

 

Uansett er dette litt prinsippsak :) Liker å kunne forholde meg til en god objektmodell som jeg jobber med.

 

Et annet poeng er at db for meg er "persistente data". Der kan være masse komplekse objekter som skal leve i runtimen til programmet og som jeg vil sende rundt omkring mellom activities uten at de skal lagres.

 

En grisete løsning.

Lagre objekter i en global static liste en plass. I Activityen så legger jeg inn en haug med indexer i Intenten slik at den vet hvor den skal hente tjenester. Altså en slags "dependency injection" bare med indexer slik at Activityen kontakter listen og henter ut tjenester på gitte indexer. Problemet fremdeles er at der må ligge en kjent global liste som ALLE må vite om. Dette bryter med prinsippene mine om å ha løse koblinger, men beste løsning så langt.

Lenke til kommentar

Jeg forstår i utgangspunktet problemet ditt, men jeg kjenner virkelig at jeg er veldig nysgjerrig på hva slags (mobil)program du lager som har behov for å sende såpass mye data mellom aktivitetene. Er det nødvendig at de dialogene du sier vil bli brukt for å redigere dataene kjenner til hele objektet? I mange tilfeller kan du kanskje klare deg med en alertdialog? Den kan bygges som en innerclass og ha tilgang til objekter som allerede er lastet av activityen...

 

Det var heller ikke beint frem å få til ren MVC i Compact Framework, og man skulle ha en viss kompleksitet på programmet for at det skulle lønne seg mtp. ekstra tidsbruk. Dessverre er det nok enda vanskeligere i Android som du sier.

 

/Espen

Lenke til kommentar
Du bør skille mellom program og brukergrensesnitt bedre hvis dette er et problem. Husk at GUI er et skall utenpå programmet.

Det er klart. Har allerede laget ca 50 domeneklasser som tar seg av diverse beregninger etc. Har ikke begynt i designe GUI/Activities ennå. Men det jeg ønsker er jo å sende inn klassene til Activityene for redigering. Ikke å programmere all logikk i activityene. Dette er heller ikke praktisk gjennomførbart

 

Jeg forstår i utgangspunktet problemet ditt, men jeg kjenner virkelig at jeg er veldig nysgjerrig på hva slags (mobil)program du lager som har behov for å sende såpass mye data mellom aktivitetene.

Det er i grove trekk en slags GIS applikasjon med objekter som inneholder informasjon om veier og lignende med relativt høy kompleksitet, og for en Android applikasjon, relativt mye data.

 

Uansett er egentlig datamengder irellevant. Eks:

Vi har en "Person" objekt som har "N" antall ordrer "Order" og dette ikke er data som skal lagres for senere bruk(vi utelukker SqlLite). Vi ønsker å se på/redigere disse dataene.

Normalt ville jeg hatt en dialog som tar inn alle "Person" objekter og velger en person. Da kan en sende inn alle ordrene til denne personen i en ny dialog for oversikt over ordrer. Hvordan ville en gjort dette "the android way". En kan jo ikke sende inn objekter? Skal en pakke ut alt dette på utsiden da. Intent.set("Fornavn", new String[]{Ole, Per, Hans}); osv? Får litt flashback til endel fæl VB kode :p Blir ikke så mye klokere på det her :hmm:

Endret av OleM80
Lenke til kommentar

LOL. Ser ut som jeg har oversett litt informasjon på Android siden: http://developer.android.com/guide/appendix/faq/framework.html

 

A HashMap of WeakReferences to Objects

You can also use a HashMap of WeakReferences to Objects with Long keys. When an activity wants to pass an object to another activity, it simply puts the object in the map and sends the key (which is a unique Long based on a counter or time stamp) to the recipient activity via intent extras. The recipient activity retrieves the object using this key.

 

Dette var fakisk løsningen jeg kom frem til i et tidligere innlegg. Forstod ikke helt hva de mente første gangen jeg leste den artikkelen. Bare at jeg bruker det som en generell "Dependency Injection" lignende sak. Dvs. jeg tenker å sende inn flere indexer på denne måten for å sette alle tjenester og lignende. Da er faktisk ikke den tanken så dum sikkert i og med at Android gjengen selv anbefaler den.

 

Det er fremdeles ikke svar på hvorfor jeg ikke kan gjøre som i C++,C#, Java etc. Instansiere dialogen, sette parametere, kjøre show, hente ut data.

Lenke til kommentar

Kjenner til dette. Men fremdeles så gir den bare primitiver i retur. Måten jeg tydeligvis må løse dette på er dokumentert på Android siden som jeg forklarte i forrige innlegget mitt.

 

A HashMap of WeakReferences to Objects

You can also use a HashMap of WeakReferences to Objects with Long keys. When an activity wants to pass an object to another activity, it simply puts the object in the map and sends the key (which is a unique Long based on a counter or time stamp) to the recipient activity via intent extras. The recipient activity retrieves the object using this key.

 

Med andre ord må jeg legge det aktuelle objektet i en global hashmap for så å sende med indexen inn i onActivityResult. for så å slå opp i arrayet for å hente ut objektet inne i denne metoden. Etter min mening en håpløst måte å gjøre det på. Hadde intentene støttet objekter så hadde saken vært en annen.

Lenke til kommentar

Her er det et svar på hvordan du kan sende med egne objecter i en intent mellom activityene: how-to-send-an-object-from-one-android-activity-to-another-with-intent-putextra

 

Har vært innom dette også. Men problemet også her er at det blir laget nye objekt. La oss si at vi sender inn objektet blir det laget en parcable og et nytt objekt blir generert som en kan redigere på. Men det gamle objektet blir jo fremdeles ikke endret.

 

I logikken min kan jeg f.eks. ha et objekt, et punktklasse. Denne kan blir brukt i masse sammenhenger og kanskje 10 andre objekter har en referanse til dette objektet.

 

Hvis jeg åpner en dialog for å endre på dette punktet og endrer X ønsker jeg selvsagt alle alle som refererer til objektet skal få oppdatert sitt objekt. Det parcable gjør er jo egentlig å lage en klone og dermed blir jo ingenting endret. Løsningen kan f.eks. være å tilbakekopiere alle verdier etter at activityen er lukket.

 

Løsningen jeg vel egentlig baserer meg på at at da må punktet være static aksessertbart via et array eller noe så sender jeg med indexen inn i Activityen. Noe som forslått av Android utviklerne selv. Synes ikke dette er noen optimal løsning selv da programmet blir mindre løst koblet men det gjør nå jobben på et vis.

Lenke til kommentar

Du kan som sagt tideligere ikke sende objekter som parameter igjennom android. Å klage på dette er som å klage på at du ikke kan overstyre operatorer eller arve fra flere klasser. Uansett hvor godt argument eller work around du prøver å finne støttes ikke rutinen. Adapt =)

 

Dersom du på død å liv ønsker en slags fake constructor kan du subklasse Activity og intent, og sørge for at intenten setter ressursen (til feks en statisk hashmap) og passer nøkkelen til activity, I activityen henter onCreate den opp ressursen for nøkkelen og setter til et felt. onDestroy kan frigjøre ressursen igjen. Generics kan benyttes for å holde rede på Objekt typen om du ønsker å gjøre dette "dynamisk" også, uten tap av ytelse (at det ikke er tap av ytelse tar jeg som en selvfølge, men jeg kjenner ikke google sin implementasjon godt nok til å kunne bevise det).

 

Dog jeg ville ikke anbefale noe slikt, bare deal med det å benytt enten en global modell alle activities jobber mot eller en dedikert modell for hver activity, der en slags master kan til slutt sy sammen dataen når det trengs.

Lenke til kommentar

Du kan som sagt tideligere ikke sende objekter som parameter igjennom android. Å klage på dette er som å klage på at du ikke kan overstyre operatorer eller arve fra flere klasser. Uansett hvor godt argument eller work around du prøver å finne støttes ikke rutinen. Adapt =)

 

Dersom du på død å liv ønsker en slags fake constructor kan du subklasse Activity og intent, og sørge for at intenten setter ressursen (til feks en statisk hashmap) og passer nøkkelen til activity, I activityen henter onCreate den opp ressursen for nøkkelen og setter til et felt. onDestroy kan frigjøre ressursen igjen. Generics kan benyttes for å holde rede på Objekt typen om du ønsker å gjøre dette "dynamisk" også, uten tap av ytelse (at det ikke er tap av ytelse tar jeg som en selvfølge, men jeg kjenner ikke google sin implementasjon godt nok til å kunne bevise det).

 

Dog jeg ville ikke anbefale noe slikt, bare deal med det å benytt enten en global modell alle activities jobber mot eller en dedikert modell for hver activity, der en slags master kan til slutt sy sammen dataen når det trengs.

 

Hei :) Har nok gjort som du sier allerede :) Tilpasset meg! Og for all del, Løsningene fungerer de.

 

Må også poengtere at jeg ikke ønsker å "bryte" design prinsippene/best practises som google og andre praktiserer. Ønsker å lære meg å utvikle på plattformen slik google har tenkt og dette er også det jeg ønsker å finne ut mere om. men sliter å få dette til å skalere for større programmer (foreløpig).

 

I de siste innleggene mine går det mer på at jeg lurer på hvorfor de har gjort som de har gjort. Og skjønner at det ikke er dumme folk som har laget det her, De har sikkert velbegrunnede argumenter for arkitekturvalgene de har gjort. Problemet er at dette finner jeg ingenting om. Hvorfor gå så fundamentalt bort fra designprinsipper fra både Java og .NET når de samtidig bygger plattformen sin på Java?

 

Det kunne vært aktuelt å lage en større applikasjon for Android. Tilsvarende flere årsverk og sikkert 150000+ kodelinjer (Delvis porting fra .NET Compact Framework). Men er usikker på om plattformen rett og slett skalerer godt nok til å kunne gjøre dette på en god måte. Dette er informasjon som jeg savner, både fordi plattformen er veldig fersk, og fordi veldig mye av programmene som blir laget til nå er små enkle programmer uten mye kompleksitet, mange dialoger etc.

Endret av OleM80
Lenke til kommentar

Antall kodelinjer betyr jo ikke allverden, men jeg ser ikke helt grunnen til å plassere veldig avanserte programmer på en android plattform. Plassere altfor mye kode ut slik vil jo uansett gjøre jobber tyngre for utvikler enn den trenger å være.

 

Jeg har planer om etter hvert å tilby mine kunder enkel fakturering og ordre registrering over android (jobber i dag som utvikler på et ERP system), og jeg ser ingen problem med dette. Hva slags avansert funksjonalitet er det du har planer om å plassere på android?

 

Høres egentlig ut som det er noe som egentlig burde ligge på en server der android kun er en lett gui på toppen av det hele =)

 

Når det kommer til valgene google har tatt regner jeg med fokus har vært å gjøre ting enklet for relativt ferske utviklere. Regner med de erfarte hvor mye bedre det er å gjøre ting enkelt for nye utviklere enn det er å gjøre det kjempeavansert, men vansklig å starte. Se feks mot iphone og symbian, er helt klart hvilken retning som viste seg best der =)

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...