1. Mort, 08.10.2010 #1
    Mort

    Mort Threadstarter Android-Lexikon

    Hallo, mal ein Problem, dass wahrscheinlich nicht mit Android zu tun hat, mich aber schon länger nervt.
    Ich habe für die "mischen über alle Ordner"-Funktion im MortPlayer folgenden Code (leicht gekürzt):
    Code:
    Random rand = new Random( new Date().getTime() );
    int start = 0;
    List<Integer> foldersDeck = new ArrayList<Integer>();
    List<Integer> filesDeck = new ArrayList<Integer>();
            
    for ( alle Dateien in den ersten, zufälligen Ordnern ) {
        foldersDeck.add( shuffleFolders[i] );
        filesDeck.add( ii );
    }
            
    int fileCount = Math.min(maxFilesForShuffleAll, filesDeck.size());
    shuffleFolders = new int[fileCount];
    shuffleFiles   = new int[fileCount];
    
    /* etwas Handling um aktuelle und ggf. gewählte nächste Datei an den
    Anfang der Liste zu setzen */
    
    for ( int i = start; i < fileCount && filesDeck.size() > 0; i++ ) {
        pos = rand.nextInt( filesDeck.size() );
        shuffleFolders[i] = foldersDeck.get(pos);
        shuffleFiles[i]   = filesDeck.get(pos);
        foldersDeck.remove(pos);
        filesDeck.remove(pos);
    }
    (shuffleFolders und shuffleFiles sind private int[]-Properties der Klasse)

    Jetzt bekomme ich gelegentlich Fehlermeldungen, die eine ArrayIndexOutOfBoundsException bei "shuffleFolders = foldersDeck.get(pos);" enthalten. Ich kann mir aber nicht erklären, wie das zustande kommen kann, und selbst konnte ich den Fehler noch nicht nachvollziehen. Übersehe ich irgendwas wichtiges?
    Eigentlich müssten foldersDeck und filesDeck gleich groß sein, sie werden an nur einer Stelle gleichzeitig gefüllt. rand.nextInt dürfte keinen Wert über dem höchsten Index liefern. i kann nicht größer als fileCount werden, das kurz vorher als Array-Größe verwendet wurde. Wo kommt da ein ungültiger Index her???
    (Dass shuffeFiles/Folders zwischendurch per Multithreading auf andere Arrays zeigen ist übrigens auch sehr unwahrscheinlich, der Code läuft in einem synchronized-Block und wird ohnehin nicht allzu oft aufgerufen).
     
  2. swordi, 08.10.2010 #2
    swordi

    swordi Gewerbliches Mitglied

    was sein könnte

    pos = rand.nextInt( filesDeck.size() );

    pos kann hier gleich der size sein

    beim get müsste es aber dann pos-1 sein, da 0 basiert

    beispiel

    filesDeck hat 10 einträge

    pos = 10 ( weil .size() )

    get(10) ist aber zuviel, da 0-9

    lg
     
  3. Mort, 08.10.2010 #3
    Mort

    Mort Threadstarter Android-Lexikon

    Laut JavaDoc eigentlich nicht: "Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence."
     
  4. swordi, 08.10.2010 #4
    swordi

    swordi Gewerbliches Mitglied

    ok

    aber war ein versuch wert ;)
     
  5. ko5tik, 08.10.2010 #5
    ko5tik

    ko5tik Android-Experte

    Poste mal deine Stacktrace....
     
  6. Mort, 08.10.2010 #6
    Mort

    Mort Threadstarter Android-Lexikon

    Der hilft an der Stelle vermutlich nicht viel. Die Exception ist direkt an der Stelle ohne "Zwischenklassen", danach kommt der übliche Kram bis zum Aufruf, z.B.
    Code:
    java.lang.ArrayIndexOutOfBoundsException
        de.stohelit.folderplayer.playback.FolderManager.fillShuffleAll(FolderManager.java:1686)
        de.stohelit.folderplayer.playback.FolderManager.gotoTrack(FolderManager.java:1137)
        de.stohelit.folderplayer.playback.PlaybackService$7.gotoTrack(PlaybackService.java:1592)
        de.stohelit.folderplayer.TrackList$7.onClick(TrackList.java:427)
        com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:876)
        ....
     
  7. Blalasaadri2, 08.10.2010 #7
    Blalasaadri2

    Blalasaadri2 Android-Hilfe.de Mitglied

    Ich kenne mich zwar mit Android-Java noch nicht aus, aber in "normalem" Java (J2SE) würde ich einfach mal ein
    Code:
    System.out.println("[FONT=monospace]filesDeck.size() = [/FONT]" + filesDeck.size() 
                     + ", foldersDeck.size() = " + foldersDeck.size() 
                     + ", pos = " + pos);
    nach der Änderung der pos-Variable einfügen und schauen, bei welchen Werten diese Exception kommt. Erfahrungsgemäß vertut man sich da gern mal um 1.

    Gruß,
    Blalasaadri
     
  8. Kranki, 08.10.2010 #8
    Kranki

    Kranki Ehrenmitglied

    Ist die erste for-Schleife sehr komplex oder geheim? Ich seh da nämlich ein Array in dem Ausschnitt, den du gepostet hast, und die beiden in der zweiten Schleife würd ich fast ausschließen.
    Code:
    for ( alle Dateien in den ersten, zufälligen Ordnern ) {
        foldersDeck.add( shuffleFolders[i] );
        filesDeck.add( ii );
    }
     
  9. Mort, 10.10.2010 #9
    Mort

    Mort Threadstarter Android-Lexikon

    Ne, das nicht. Nur etwas verwirrend, und eigentlich geht's an der Stelle ja nur darum, dass die beiden Deck-Arrays gleichzeitig an derselben Stelle gefüllt werden.

    Code:
            fillShuffleFolders(); // füllt shuffleFolders mit den Ordner-Indizes in zufälliger Reihenfolge. Nach dem Füllen der Decks wird dieser Array "weggeworfen" (out of scope via folderArray = new ...)
    
            for ( int i = 0; i < shuffleFolders.length && foldersDeck.size() < maxFilesForShuffleAll*2; i++ ) {
                FolderInfo folder = foldersWithFiles.get( shuffleFolders[i] );
                for ( int ii = 0; ii < folder.getPlayableFiles(); ii++ ) {
                    // aktuelles und nächstes File werden hinterher
                    // an den Anfang verfrachtet, deshalb hier ignoieren
                    if ( ( shuffleFolders[i] != currentFolderIndex 
                            || ii != currentFileIndex )
                        && ( nextFileIndex == -1
                                || shuffleFolders[i] != nextFolderIndex 
                                || ii != nextFileIndex )
                        ) {
                        foldersDeck.add( shuffleFolders[i] );
                        filesDeck.add( ii );
                    }
                }
            }