2010. július 7., szerda

EasyTop 0.1


Egy kicsit ugrunk. A hello world-öt, illetve egyéb alap dolgokat a dev guide, illetve egyéb leírások alapján egész egyszerűen össze lehet hozni. Most inkább egy konkrét feladat megoldását mutatnám be.

Többször is szükségem lett volna arra, hogy lássam melyik processz terheli le a telefon CPU-ját. Erre van ugyan megoldás a marketen is, de van olyan egyszerű a probléma, hogy érdemes lenne gyakorlásképpen megoldani.
A megoldás kulcspontjai:
  • top (ezt semelyik linuxosnak nem kell bemutatni)
  • egy handler objektum (h)
  • egy futtatható objektum (updateTimeTask)
A koncepció:

Egy activitynek jól meghatározható életciklusa van, ami csak user beavatkozásra iterálhat. Ezt úgy kell érteni, hogy pl. C-ben a main függvényben simán írhatunk egy ciklust, ami időközönként beolvassa top parancs kimenetét, majd megjeleníti, de itt nem járható ez az út.

Megoldás:

Szükségünk van egy objektumra, amely bizonyos időközönként beállítja egy textview szövegét, ez lesz az updateTimeTask, amely Runnable típusú. Ugyanis egy handler queue-jába ilyen típusú objektumokat is betehetünk, méghozzá úgy is, hogy a tényleges lefutás idejét eltolhatjuk (postDelayed). Az updateTimeTask run metódusában pedig egyszerűen saját magát kell beletennie a handler queue-jába, így kvázi rekurzióval tudunk iterálni.

Tehát hogy néz ki az activity-nk :
A textview, ami a kimenetet jeleníti meg:

private TextView tv;


A handler:
private Handler h = new Handler();

A futtatható objektumunk:

private Runnable updateTimeTask = new Runnable() {
public void run() {
refreshTv();
h.postDelayed(this, 1000);
};
};

Nézzük meg hogy a run metódusban frissíti a textview-t, majd beleteszi saját magát a handler queuejába. Amikor kikerül, és lefut, megint beteszi magát biztosítva a folyamatos frissítést.

A metódus, ami frissíti textview-t:

private void refreshTv() {
String text = ""; try {
InputStream ios = Runtime.getRuntime().exec("top -n 1 -m 5").getInputStream();
InputStreamReader iosReader = new InputStreamReader(ios);
BufferedReader bffr = new BufferedReader(iosReader);
String line;
while ((line = bffr.readLine()) != null ) {
if(line.trim().length() != 0) {
text = text + "\n" + line.trim();
};//else nop
};
} catch(Exception e) {
text = "IO error";
}; tv.setText(text);
//a kovetkezo kettot lehet, hogy eleg lenn Oncreate idoben
tv.setTextSize(12);
tv.setTypeface(Typeface.MONOSPACE,Typeface.NORMAL);
};
A koncepció system hívásként lefuttatva a topot elkajuk a kimenetét, feldolgozzuk, és a textview-nak értékül adjuk.

onCreate időben beállítjuk az alapdolgokat, és elindítjuk a folyamatot:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
refreshTv();
setContentView(tv); h.removeCallbacks(updateTimeTask);
h.postDelayed(updateTimeTask, 1000);
};

A megoldás korántsem a legjobb, de a legegyszerűbb, tehát tanuló programnak teljesen jó volt.

Az eredmény:


Amit lehet majd még javítani rajta:
  • táblázatos megjelenítés
  • frissítés külön threadben
  • különböző user által állítható paraméterek (pl most fixen 5 processz látszik csak)
A teljes kód letölthető innen.

Ha valami kérdés, probléma, óhaj, sóhaj merülne fel, akkor comment-ben jelezzétek.

Nincsenek megjegyzések:

Megjegyzés küldése