Android Performance fragen

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von Raidri, 11.10.2011.

  1. Raidri, 11.10.2011 #1
    Raidri

    Raidri Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    71
    Erhaltene Danke:
    1
    Registriert seit:
    27.03.2010
    Hallo,

    man liest im Inet unterschiedliche Meinungen über static Variablen. Was ich gerne wissen würde ist, sollte man erzeugte Textviews, buttons etc. als static deklarieren, dass man sie nicht immer wieder neu erzeugen muss oder lässt man dies sein?

    Eine andere Frage ist, ich habe eine Klasse die verschiedene Arraylist beinhaltet. Diese Daten in den Arraylist, werden sehr oft in verschiedenen Teilen des Programmes benötigt. Also habe ich das object zu dern Arraylists static gemacht. Also z.b.

    meine klasse heißt data. Die hat eine Singleton Funktion, wo sich das Objekt selbst erzeugt. Dieses Objekt nutze ich dann überall und kann z.B. sagen data->getCustomerList(). Also bleibt das Objekt immer am leben. Nur ist das wirklich sehr performant.

    Die letzte und für mich wichtigste Frage ist das Thema asyncTask. Ich verwende davon bestimmt 7-8 Stück in meinem Code. Ist sowas schädlich für die Performance besser gesagt, wie kann ich diese asyncTaks sicher beenden? Der Debugger von Eclipse zeigt diese immer als "running" an, obwohl die onPostExecute Methode Fertig war.

    Vielen Danke für die Antworten. Wenn ihr noch weitere Tipps für mich habt, würde ich mich darüber freuen ;).

    Gruß
    Raidri
     
  2. sixi, 11.10.2011 #2
    sixi

    sixi Erfahrener Benutzer

    Beiträge:
    237
    Erhaltene Danke:
    64
    Registriert seit:
    20.01.2009
    Nein, dass macht keinen Sinn. Die sinnvolle Lösung ist, die TextViews als Member-Variablen in deiner Activity zu deklarieren: die TextViews "existieren" ja nur, wenn die Activity angezeigt wird, also warum solltest du z.B. von einer anderen Activity auf diese zugreifen (sprich sie im Static-Context zur Verfügung stellen).

    Kann man machen. Ob das sinnvoll ist hängt von den Daten ab, die da enthalten sind - und wieviel davon du nutzt: Angenommen du hälst 200 Wikipedia Artikel in der Variable bereit, dann belegt diese dauerhaft Speicher. Wenn du von denen nur 10 wirklich nutzt macht es mehr Sinn diese ad-Hoc zu "laden"...
    Aber das Prinzip ist nicht so verkehrt.

    Kein Problem! Wenn die Async-Task Objekte noch als "lebend" angezeigt werden liegt das daran, dass der Garbage-Collector sie noch nicht abgeholt hat. Könntest du durch einen manuellen Aufruf forcieren.
    Das einzige Problem, was ich bislang im Zusammenhang mit AT festgestellt hab: wenn du z.B. eine Liste hast und für jedes Listen-Element einen AsyncTask erstellst (z.B. um Bilder nachzuladen) - und dann seeeehr schnell durch die liste scrollst fliegt dir das ganze irgendwann um die Ohren, weil der ThreadPool bei Android beschränkt ist. Ansonsten werden AsyncTasks in der Android-Docu unter "painless Threading" geführt, also nutz sie ruhig.
    Ich glaube der gewinn, wenn du die AT durch "normale" Threads ersetzt und dann jeweils selbst dafür sorgst dass die änderungen wieder im UI-Thread landen dürfte minimal oder nicht vorhanden sein ;)
     
    Raidri bedankt sich.
  3. Raidri, 11.10.2011 #3
    Raidri

    Raidri Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    71
    Erhaltene Danke:
    1
    Registriert seit:
    27.03.2010
    Das mit dem GC muss ich mal ausprobieren. Es gibt nämlich Situationen wo meine App nie Probleme macht und auf einmal kackt es am Ende eines asyncTask ab. Alle Daten sind geladen und sie müssten nurnoch in der Liste angezeigt werden, stattdessen sehe ich kurz ne leere Liste und dann bekomme ich den app absturz.

    Besten dank
     
  4. sixi, 11.10.2011 #4
    sixi

    sixi Erfahrener Benutzer

    Beiträge:
    237
    Erhaltene Danke:
    64
    Registriert seit:
    20.01.2009
    Wenn du die Tasks in ner Liste für jedes Element erzeugst, versuch mal die ausführung leicht zu verzögern, also z.B. in der doInBackground nen sleep für 200ms und danach prüfen, ob das Listen-Element, zu dem der Task gehört überhaupt noch angezeigt wird.
     
  5. Raidri, 11.10.2011 #5
    Raidri

    Raidri Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    71
    Erhaltene Danke:
    1
    Registriert seit:
    27.03.2010
    Ich lade über einen service sagen wir mal 20 Kunden. Diese packe ich in eine Arraylist und übergebe diese liste dann bei onPostExecute, an meinen adapter der mit der Listview verbunden ist. Ich habe bei dem Thema schon fast die Vermutung das es nen Speicherproblem sein könnte, aber sicher bin ich da auch nicht. Deswegen stelle ich diese Performance Fragen.

    Aber vielleicht habe ich ja auch Glück und es hängt tatsächlich nur an dem sammelsurium von aSyncTaks. Muss ich mal genauer beobachten.
     
  6. the_alien, 11.10.2011 #6
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Stacktraces helfen ;)
     
  7. Raidri, 11.10.2011 #7
    Raidri

    Raidri Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    71
    Erhaltene Danke:
    1
    Registriert seit:
    27.03.2010
    Genau das habe ich vor mit "genauer Beobachten" :). Trotzdem Danke
     
  8. Raidri, 11.10.2011 #8
    Raidri

    Raidri Threadstarter Android-Hilfe.de Mitglied

    Beiträge:
    71
    Erhaltene Danke:
    1
    Registriert seit:
    27.03.2010
    Hallo,

    ich konnte das Problem ausfindig machen und bräuchte dabei eure Hilfe.

    Die Meldung ist wie folgt:

    "Unable to add Window token android.os.Binderproxy ist not valid"

    Dies passiert in folgendem Code:

    Code:
    private class CallSpecifiedData extends AsyncTask<Void, Void, Void>
    	{
    		 public boolean res = false;
    		 @Override
    	     protected void onPreExecute() {
    			 if(adapter instanceof ProjectAdapter){
    				 final String type = ((ProjectAdapter)adapter).getFilterType();
    				 if(type.equals("Activ")){
    					 dialog = ProgressDialog.show(adapter.getContext(),adapter.getContext().getResources().getString(R.string.loadArchivProjectsTitle),adapter.getContext().getResources().getString(R.string.loadArchivProjects));
    				 }
    				 else
    				 {
    					 dialog = ProgressDialog.show(adapter.getContext(),adapter.getContext().getResources().getString(R.string.loadActivProjectsTitle),adapter.getContext().getResources().getString(R.string.loadActivProjects));
    				 }
    			 }
    			 else  if(adapter instanceof CustomerAdapter){
    				 final String type = ((CustomerAdapter)adapter).getFilterType();
    				 if(type.equals("Activ")){
    					 dialog = ProgressDialog.show(adapter.getContext(),adapter.getContext().getResources().getString(R.string.loadArchivCustomersTitle),adapter.getContext().getResources().getString(R.string.loadArchivCustomers));
    				 }
    				 else
    				 {
    					 dialog = ProgressDialog.show(adapter.getContext(),adapter.getContext().getResources().getString(R.string.loadActivCustomersTitle),adapter.getContext().getResources().getString(R.string.loadActivCustomers));
    				 }
    			 }
    			 else  if(adapter instanceof ServiceAdapter){
    				 final String type = ((ServiceAdapter)adapter).getFilterType();
    				 if(type.equals("Activ")){
    					 dialog = ProgressDialog.show(adapter.getContext(),adapter.getContext().getResources().getString(R.string.loadArchivServicesTitle),adapter.getContext().getResources().getString(R.string.loadArchivServices));
    				 }
    				 else
    				 {
    					 dialog = ProgressDialog.show(adapter.getContext(),adapter.getContext().getResources().getString(R.string.loadActivServicesTitle),adapter.getContext().getResources().getString(R.string.loadActivServices));
    				 }
    			 }
    	     }
    		
    		@Override
    		protected Void doInBackground(Void... params) {
    			res = callData();
    			return null;
    		}
    		 @Override
    	    protected void onPostExecute(Void result) {
    
    			 try
    			 {
    	            if(res)
    	            {
    	            	dialog.dismiss();
    	            	
    	            	if(adapter instanceof ProjectAdapter){
    	        			final String type = ((ProjectAdapter)adapter).getFilterType();
    	        			if(type.equals("Activ")){
    	        				((ProjectAdapter)adapter).clear();
    	        				((ProjectAdapter)adapter).setProjects(DataCaller.miteData.getArchivedProjects());
    	        				((ProjectAdapter)adapter).setFilterType("Archiviert");
    	        			}
    	        			else{
    	        				((ProjectAdapter)adapter).clear();
    	        				((ProjectAdapter)adapter).setProjects(DataCaller.miteData.getActiveProjects());
    	        				((ProjectAdapter)adapter).setFilterType("Activ");
    	        			}
    	        			((ProjectAdapter)adapter).getFilter().filter("");
    	        			if(adapter.getCount() == 1)
    	        			{
    	        				wholeView.setText("("+adapter.getCount()+" "+wholeView.getResources().getString(R.string.projectSingle)+")");
    	        			}
    	        			else
    	        			{
    	        				wholeView.setText("("+adapter.getCount()+" "+wholeView.getResources().getString(R.string.project)+")");
    	        			}
    	        		}
    	        		else if(adapter instanceof CustomerAdapter){
    	        			final String type = ((CustomerAdapter)adapter).getFilterType();
    	        			if(type.equals("Activ")){
    	        				((CustomerAdapter)adapter).clear();
    	        				((CustomerAdapter)adapter).setCustomers(DataCaller.miteData.getArchivedCustomers());
    	        				((CustomerAdapter)adapter).setFilterType("Archiviert");
    	        			}
    	        			else{
    	        				((CustomerAdapter)adapter).clear();
    	        				((CustomerAdapter)adapter).setCustomers(DataCaller.miteData.getActiveCustomers());
    	        				((CustomerAdapter)adapter).setFilterType("Activ");
    	        			}
    	        			((CustomerAdapter)adapter).getFilter().filter("");
    	        			if(adapter.getCount() == 1)
    	        			{
    	        				wholeView.setText("("+adapter.getCount()+" "+wholeView.getResources().getString(R.string.customerSingle)+")");
    	        			}
    	        			else
    	        			{
    	        				wholeView.setText("("+adapter.getCount()+" "+wholeView.getResources().getString(R.string.customer)+")");
    	        			}
    	        		}
    	        		else if(adapter instanceof ServiceAdapter){
    	        			final String type = ((ServiceAdapter)adapter).getFilterType();
    	        			if(type.equals("Activ")){
    	        				((ServiceAdapter)adapter).clear();
    	        				((ServiceAdapter)adapter).setServices(DataCaller.miteData.getArchivedServices());
    	        				((ServiceAdapter)adapter).setFilterType("Archiviert");
    	        			}
    	        			else{
    	        				((ServiceAdapter)adapter).clear();
    	        				((ServiceAdapter)adapter).setServices(DataCaller.miteData.getActiveServices());
    	        				((ServiceAdapter)adapter).setFilterType("Activ");
    	        			}
    	        			((ServiceAdapter)adapter).getFilter().filter("");
    	        			if(adapter.getCount() == 1)
    	        			{
    	        				wholeView.setText("("+adapter.getCount()+" "+wholeView.getResources().getString(R.string.serviceSingle)+")");
    	        			}
    	        			else
    	        			{
    	        				wholeView.setText("("+adapter.getCount()+" "+wholeView.getResources().getString(R.string.service)+")");
    	        			}
    	        		}
    	            }
    			 }
    			 catch(Exception e)
    			 {
    				 
    			 }
    	           
    		 }
    	}
    Vielleicht noch gut zu wissen. Diese Funktion wird in keiner activity ausgeführt sondern in einem listener. Was man aus dem Inet lesen kann ist, dass dieses Problem wohl mit dem Dialog zu tun hat, aber was kann man da tun?

    Besten dank für die erneute Hilfe :).

    Gruß
    Raidri
     

Diese Seite empfehlen