Firebase ListView mit Countdown // Skipped Frames // mit video

  • Antworten:9
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 6

28.05.2018, 12:07:36 via Website

Ich begrüße vorweg alle hier im Forum

Ich bin schon längere Zeit ein stiller Mitleser. Habe oft lange alleine probiert und die Suchfunktion benutzt. Doch trotzdem bin ich auf Hilfe angewiesen.

Zu meinen Problem.

Ich habe eine Liste im Fragment die mit Daten aus der Firebasedatenbank gefüllt wird.
im jeden ListRow ist ein Countdown Timer der aus den Zeitstempel berechnet wird der auf der Bank liegt.

Daten sollen im Hintergrund aktualisiert werden.

Wenn ich mein Server sage er soll mehrere Spiele bereit stellen spinnt der erste und der letzte Countdowntimer und Es fängt nach einer kurzen zeit an zu hacken, egal ob ein oder mehrere Spiele . Zum besseren Nachvollziehen hab ich ich 2 Videos hochgeladen.
leider kann ich noch keine links teiln, deswegen die titel der videos
-> Titel ... "background timer .. skipped frames"
-> Titel ... "mehrere games .. erster und letzter timer spinnen"

und die Code Schnipsel

Code vom Fragment

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    gameList = view.findViewById(R.id.listview_games);

    switch (item.getItemId()) {

        case R.id.btn_1c:


            try {

                gameKatego = 1;
                firebaseDatabase = FirebaseDatabase.getInstance();

                AdapterAsyncstarten(gameKatego,mutchGames,gameList,gameInfoList,firebaseDatabase);


            } catch (Exception e) {

                System.out.println("fehler ------ ....." + e.getMessage());

            }

            gameList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View views, int position, long id) {


                }
            });

            return true;

private void AdapterAsyncstarten(int gameKatego, int mutchGames, ListView gameList, ArrayList fireGameList, FirebaseDatabase firebaseDatabase) {

    //Log.e("in fireinfo"," log vor asynstrt ");
    GamelistAdapterAsynTask gamelistAdapterAsynTask = new GamelistAdapterAsynTask(getActivity(),gameKatego,mutchGames,gameList,fireGameList,firebaseDatabase);
    gamelistAdapterAsynTask.execute();




}

Code von GamelistAdapterAsynTask

GamelistAdapterAsynTask(FragmentActivity activity, int gameKatego, int mutchGames, ListView gameList, ArrayList fireGameList, FirebaseDatabase firebaseDatabase) {

    this.activity = activity;
    this.context = activity;
    this.gameKatego = gameKatego;
    this.mutchGames = mutchGames;
    this.gameList = gameList;
    this.fireGameList = fireGameList;


    this.gameNumb = new int[mutchGames + 1];
    this.restTime = new long[mutchGames + 1];
    this.gameId = new int[mutchGames + 1];
    this.bestPlayer = new String[mutchGames + 1];
    this.coinValue = new int[mutchGames + 1];
    this.playerSize = new int[mutchGames + 1];
    this.playAble = new boolean[mutchGames + 1];


}

@Override
protected ListAdapter doInBackground(Void... voids) {


    try {


    activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            gameList.setAdapter(null);
            fireGameList.clear();
        }
    });

    int i = 1;

    do {
        firebaseFetchData(i);
        i++;
    } while (i <= mutchGames);

    //Thread.sleep(200);

        for (int w = 0 ; w<=100000000;w++){

            // diese Schleife musste ich tätigen weil die daten sonst nicht ankommen würden

        }

    for (int b = 1; b <= mutchGames; b++ ) {
        Log.e("b loop" , " " + b);
        fireGameList.add(new ListRowInfo(gameKatego, b, restTime[b], gameId[b], bestPlayer[b], coinValue[b], playerSize[b]));
    }

    firebaseListAdapter = new FirebaseListAdapter(activity,
            fireGameList,R.layout.list_row,gameList,
            gameKatego,mutchGames);

        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {

                gameList.setAdapter(firebaseListAdapter);


            }
        });

}catch (Exception e){
    System.out.println("fehler im asynctask " + e.getMessage());
}


    return null;
}


@Override
protected void onPostExecute(ListAdapter adapter) {
    super.onPostExecute(adapter);

    Log.e("postexecute" , " " );




}

Code ListAdapter

 public static class ViewHolder {
    TextView tv_bestplayer;
    TextView tv_restTime;
    TextView tv_playerSize;
    TextView tv_einsatz;
}


FirebaseListAdapter(Context applicationContext, ArrayList<ListRowInfo> gameInfoClass, int list_row, ListView gameList, int gameKatego, int mutchGames) {
    super(applicationContext, list_row, gameInfoClass);
    this.context = applicationContext;
    this.gameinfos = gameInfoClass;
    this.listRow = list_row;
    this.listView = gameList;
    this.gameKatego = gameKatego;
    this.mutchGames = mutchGames;
    this.timerThread = new Thread[mutchGames+1];
    this.countDownTimerTask = new CountDownTimerTask[mutchGames+1];


    //Log.e("bis","hier" +gameInfoClass.size());

}

@Override
public boolean areAllItemsEnabled() {
    return false;
}

@Override
public boolean isEnabled(int position) {

    return gameinfos.get(position).getRestTime() > System.currentTimeMillis();
}


@Override
public int getCount() {
    if (gameinfos.size() <= 0)
        return 0;

    //Log.e("modelsize ", "modelsize " + gameinfos.size());
    return gameinfos.size();
}

@Override
public ListRowInfo getItem(int position) {
    return gameinfos.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}


private int lastPosition = -1;

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ListRowInfo curretsInfos = getItem(position);

    //Log.e("position ","position "+position);


    ViewHolder viewHolder;
    final View result;

    if (convertView == null) {
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(context);
        convertView = inflater.inflate(R.layout.list_row, parent, false);
        viewHolder.tv_playerSize = (TextView) convertView.findViewById(R.id.tv_playerSize);
        viewHolder.tv_bestplayer = (TextView) convertView.findViewById(R.id.tv_bestplayer);
        viewHolder.tv_restTime = (TextView) convertView.findViewById(R.id.tv_timerDown);
        viewHolder.tv_einsatz = (TextView) convertView.findViewById(R.id.tv_einsatzValue);

        result = convertView;

        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
        result = convertView;
    }

    Animation animation = AnimationUtils.loadAnimation(context, (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top);
    result.startAnimation(animation);
    lastPosition = position;

    gameNumb = curretsInfos.getGameNumb();
    gameKatego = curretsInfos.getKategoNumb();


    countDownTimerTask[gameNumb] = new CountDownTimerTask(curretsInfos,viewHolder);
    countDownTimerTask[gameNumb].execute(curretsInfos.getRestTime(),(long)1000);

    viewHolder.tv_playerSize.setText(curretsInfos.getPlayerSize()+"");
    viewHolder.tv_bestplayer.setText(curretsInfos.getBestPlayer());
    viewHolder.tv_einsatz.setText(curretsInfos.getKategoNumb()+"");

    //viewHolder.tv_restTime.setText();


    //Log.e("log "," in adapter " + curretsInfos.getRestTime());

    //viewHolder.tv_restTime.setText(sdf.format(curretsInfos.getRestTime())+"");


    return result;

}

Ich weiß es ist etwas viel. Ich bin dankbar für jede Hilfe.
Falls ihr noch etwas wissen müsst, sagt bescheid.

Danke schon mal. LG

Diskutiere mit!
Beste Antwort
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

28.05.2018, 12:12:25 via App

Hallo Droide,

Herzlich willkommen hier im Forum :)

Ohne das Video gesehen zu haben: Hast du im Log SkippedFrames Meldungen? Wenn ja zu welchem Activity Zeitpunkt?
Vermutlich braucht irgend ein Vorgang zu lange und daher das Problem.

Evtl. mal eine RecyclerView nutzen und deine SetAdapter nicht im doInBackground, sondern im onPostExecute etc..

Zudem: Trennen von UI (Adapter Aktionen wie clear) und alden der Daten aus der DB.

Kann Firebase keine DataCallbacks? Denn wenn ja kannst du dir dir komsche for Schleife sparen

— geändert am 28.05.2018, 12:14:55

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 6

28.05.2018, 12:35:48 via Website

Also es kommt eine Skipped Meldung
Skipped 30 frames! The application may be doing too much work on its main thread.

Ansich läuft ja nur der Timer im Hintergrund , zurzeit.
der ChildEventListener ist ja nur am Anfang aktiv im BackgroundTask.
den setAdapter war vorher im PostEcecute... war nen test ihn im background zu haben. schon wieder geändert.

Ich werde es mal mit den RecyclerView probieren. Ist der besser geeignet für flexible Variablen?
Wird das ähnlich aufgebaut?

Hilfreich?
Diskutiere mit!
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

28.05.2018, 12:37:33 via App

Eine RecyclerView ist moderner und die ViewItems werden erst als View geladen wenn diese wirklich angezeigt werden sollen.
Evtl. mal mit dem Debugger durchgehen, wo Frames skipped werden

Wenn du das Gerät vom USB Debugging trennst und die App so öffnest, merkst du da die SkippedFrames oder nicht?
Wenn du das nicht merkst, dann kannst du das eher ignorieren. Die Meldung ist ja nur ein Hinweis, dass dein MainThread irgendwo hängt.

— geändert am 28.05.2018, 12:39:00

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 6

28.05.2018, 12:45:39 via Website

Leider auch ohne Kabel zu doll und mit Steigerung pro sec. wenn´s anfängt.

Ich bau mal um gucke ob es besser wird.

werde mal schauen wegen den Callback von Firebase.

Und warum spinnen bei mehreren Spielen der erste und letzte Timer? Als wenn auf den mehrere Timer liegen.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 6

28.05.2018, 14:26:50 via Website

Erstaunlich das RecyclerView reichte aus für die Performence.

jetzt nur noch klären wieso die Timer alle Überschrieben sind und mehrere Zeiten runterzählen .
Danke schon mal an Pascal P.

Hilfreich?
Diskutiere mit!
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.165

28.05.2018, 14:35:24 via App

Da ist es vlt. hilfreich den Lifecycle der Timer anzuschauen.
Evtl. werden die mal zurückgesetzt...

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 6

28.05.2018, 18:40:07 via Website

also jedes mal wenn ich die liste scrolle wird in dem listrow, in der der Timer ist, der Timer überschrieben, sobald er wieder sichbar ist.

komm gerade auch nicht selber darauf warum es so sein könnte.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 478

28.05.2018, 20:22:57 via Website

Kann Firebase keine DataCallbacks? Denn wenn ja kannst du dir dir komsche for Schleife sparen

Ja das kann Firebase. Dazu must du einen ValueEventLister der Referenz hinzufügen. Und die beider Mehoden "onDataChange" "onCancelled" überschreiben.
Somit solten Änderungen der DB in der Methode onDataChange ankommen. Ohne ständig die DB
abzufragen.

ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {

    }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 6

30.05.2018, 16:15:45 via Website

hab es mit den ChildEventlistener gelöst und das Problem mit den Countdown, dass sich die Zeiten überschreiben liegt an der Tatsache das meine Animation vorher geladen wurde und somit die positionen sich vermischt hatten , siehe Code Am Anfang im ListAdapter.

Danke für die Hilfe. Forum ist wirklich Klasse . Manchmal hilft es mit anderen einfach über sein Code zu reden(schreiben).

Hilfreich?
Diskutiere mit!

Empfohlene Artikel