简体   繁体   English

应用在Android 4.0+上崩溃

[英]App crashes on android 4.0+

I have and android app that works on android 4.0 great, but it crashes on android 4.3 and 4.4. 我有一个适用于android 4.0的android应用程序,但在android 4.3和4.4上崩溃。 I get this from the logCat 我从logCat得到这个

01-11 14:40:27.669: E/ACRA(25835): ACRA caught a IllegalStateException exception for quran. Building report.
01-11 14:40:27.789: E/AndroidRuntime(25835): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131099688, class android.widget.ListView) with Adapter(class quran.functions.PlaylistAdapter)]

Here is my code: 这是我的代码:

public class Playlist extends FragmentActivity {

    private ListView list;
    private Button manager, downloadAll;
    private TextView reciter;
    public static PlaylistAdapter adapter;
    private ArrayList<Songs> songs;
    private int RECITER_ID;
    private String url, title, label;
    private SlidingMenu slidingMenu;
    private DatabaseHelper db;
    private ImageView nowPlaying, back;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.playlist);
        initWidgets();
        list.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1,
                    int position, long arg3) {

                Intent intent = new Intent(Playlist.this, PlayerFinal.class);
                intent.putExtra("songs", songs);
                if (getIntent().getIntExtra("duaa", -1) == 115)
                    intent.putExtra("lang", 115);
                intent.putExtra("position", position);
                intent.putExtra("fromClass", this.getClass() + "");
                // intent.putExtra("mp3link", mp3link);
                startActivity(intent);
            }
        });
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {

                XmlMapParser m = new XmlMapParser(Playlist.this, RECITER_ID);
                HashMap<String, ArrayList<String>> map = m.convert();
                map.keySet();
                label = map.get("RecitorLabel").get(0);
                title = map.get("Title").get(0);
                url = map.get("Link").get(0);
                back = (ImageView) findViewById(R.id.playlist_back);
                back.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View arg0) {
                        finish();
                    }
                });
                db.openDB();
                for (int i = 1; i < map.get("Link").size(); i++) {
                    if (db.isDownloaded(i, title, RECITER_ID)) {
                        songs.add(new Songs(i, map.get("Title").get(i),
                                Environment.getExternalStorageDirectory()
                                        .getPath()
                                        + "/"
                                        + getString(R.string.app_name)
                                        + "/"
                                        + title
                                        + "/"
                                        + map.get("Title").get(i)
                                        + ".mp3", title, true, RECITER_ID,
                                false));

                    } else
                        songs.add(new Songs(i, map.get("Title").get(i), url
                                + label + "/"
                                + new DecimalFormat("000").format(i) + ".mp3",
                                title, false, RECITER_ID, false));
                }
                db.closeDB();
                // Log.v("--",m.convert().get("Link").get(1));
                // [RecitorLabel, Title, Link] THIS ARE THE KEYS m

                // Log.v("--", map.get("RecitorLabel").get(0));
                // Log.v("--", map.get("Link").get(1));
                return null;
            }

            protected void onPostExecute(Void result) {
                adapter = new PlaylistAdapter(Playlist.this, songs);
                list.setAdapter(adapter);
                reciter.setText(songs.get(0).getRecitorName());
            };
        }.execute();

    }

    @Override
    public void onBackPressed() {
        if (slidingMenu.isMenuShowing()) {
            slidingMenu.toggle();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        try {
            if (Tplayer.getInstance().isPlaying()) {
                adapter = new PlaylistAdapter(this, songs);
                list.setAdapter(adapter);
                adapter.notifyDataSetChanged();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_MENU) {
            this.slidingMenu.toggle();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            this.slidingMenu.toggle();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    private void initWidgets() {
        db = new DatabaseHelper(this);
        manager = (Button) findViewById(R.id.playlist_download_manager);
        manager.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Playlist.this, DownloadManager.class);
                startActivity(intent);
            }
        });
        reciter = (TextView) findViewById(R.id.playlist_reciter_name_top);
        list = (ListView) findViewById(R.id.playlist_list);
        downloadAll = (Button) findViewById(R.id.playlist_download_all);
        manager = (Button) findViewById(R.id.playlist_download_manager);
        songs = new ArrayList<Songs>();
        RECITER_ID = getIntent().getIntExtra("filename", -1);
        // downloadAll.setOnClickListener(new OnClickListener() {
        //
        // @Override
        // public void onClick(View v) {
        // new DownloadAll(Playlist.this, songs);
        // db.openDB();
        // for (int i = 0; i < songs.size(); i++) {
        // db.addDownloaded(songs.get(i).getNumber(), songs.get(i)
        // .getLink(), 0, songs.get(i).getRecitorID(), "",
        // songs.get(i).getTitle());
        // }
        // db.closeDB();
        // }
        // });
        nowPlaying = (ImageView) findViewById(R.id.playlist_now_playing);
        nowPlaying.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Tplayer tplayer = Tplayer.getInstance();
                if (tplayer.isPlaying()) {
                    Intent intent = new Intent(Playlist.this, PlayerFinal.class);
                    if (tplayer.isPlaying())
                        intent.putExtra("songs", tplayer.getSongs());
                    else
                        intent.putExtra("songs", songs);
                    if (tplayer.getSongs().size() == 14)
                        intent.putExtra("lang", 115);
                    intent.putExtra("position", tplayer.getPosition());
                    startActivity(intent);
                }
            }
        });
        // Jeremy Feinstein slidinglistadapter line 94
        slidingMenu = new SlidingMenu(this);
        slidingMenu.setMode(SlidingMenu.LEFT);
        slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
        slidingMenu.setShadowWidthRes(R.dimen.slidingmenu_shadow_width);
        slidingMenu.setShadowDrawable(R.drawable.slidingmenu_shadow);
        slidingMenu.setBehindOffsetRes(R.dimen.slidingmenu_offset);
        slidingMenu.setFadeDegree(0.35f);
        slidingMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
        slidingMenu.setMenu(R.layout.slidingmenu);

    }

}

and my playlist adapter class: 和我的播放列表适配器类:

public class PlaylistAdapter extends BaseAdapter {

    private Activity activity;
    private static LayoutInflater inflater = null;
    private ArrayList<Songs> data;
    private DatabaseHelper db;
    private SharedPreferences prefs;
    int playpos;
    int recitorID;

    public PlaylistAdapter(Activity a, ArrayList<Songs> songs) {
        activity = a;
        data = songs;
        db = new DatabaseHelper(a);
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        prefs = activity.getSharedPreferences("quantic.Quran",
                Context.MODE_PRIVATE);
        recitorID = prefs.getInt("recID", -1);
        playpos = prefs.getInt("posPlaying", -1);
    }

    public int getCount() {
        return data.size();
    }

    public Object getItem(int position) {
        return position;
    }

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

    public View getView(final int position, View convertView,
            final ViewGroup parent) {
        View vi = convertView;
        if (convertView == null)
            vi = inflater.inflate(R.layout.song_item, parent, false);

        ImageView download = (ImageView) vi
                .findViewById(R.id.playlist_item_download);
        db.openDB();
        if (db.isDownloaded(data.get(position).getNumber(), data.get(position)
                .getRecitorName(), data.get(position).getRecitorID()))
            download.setImageResource(R.drawable.download_yes);
        else {
            download.setImageResource(R.drawable.download_no);
            download.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {

                    new DownloadFileFromURL(activity, data.get(position)
                            .getRecitorName(), data.get(position).getTitle(),
                            data.get(position).getLink(), data.get(position)
                                    .getNumber(), data.get(position)
                                    .getRecitorID()).execute();
                    if (!db.isDBOpen())
                        db.openDB();
                    db.addDownloaded(data.get(position).getNumber(),
                            data.get(position).getLink(), 0, data.get(position)
                                    .getRecitorID(), "", data.get(position)
                                    .getTitle());

                    Toast.makeText(activity,
                            "Downloading " + data.get(position).getTitle(),
                            Toast.LENGTH_SHORT).show();

                }
            });
        }
        db.closeDB();

        TextView number = (TextView) vi.findViewById(R.id.playlist_item_num);
        TextView reciterName = (TextView) vi
                .findViewById(R.id.playlist_item_reciterName);
        reciterName.setText(data.get(position).getRecitorName());
        if (activity.getClass() == Playlist.class) {
            reciterName.setVisibility(View.GONE);
        }
        TextView title = (TextView) vi.findViewById(R.id.playlist_item_reciter);
        title.setText(data.get(position).getTitle());
        number.setText((position + 1) + "");
        ImageView eq = (ImageView) vi.findViewById(R.id.playlist_item_equlizer);
        if (Tplayer.getInstance().isPlaying())
            if (Tplayer.getInstance().getPosition() == position
                    && data.get(position).getRecitorID() == Tplayer
                            .getInstance().getSong().getRecitorID()) {
                eq.setVisibility(View.VISIBLE);
                Ion.with(eq).load("http://darkodev.info/quran/dots.gif");
            } else {
                eq.setVisibility(View.GONE);
            }

        return vi;
    }
}

Very old question, but no answer. 很老的问题,但没有答案。 I'm sure you have found a fix by now, but anyway. 我确定您现在已经找到了解决方法,但是无论如何。

You're changing the songs list object in background, and if Android decides to redraw your list (user scrolls your list), effectively accessing the songs list object, it may have changed and cause this exception to be thrown. 您正在后台更改歌曲列表对象,并且如果Android决定重新绘制列表(用户滚动您的列表),从而有效地访问歌曲列表对象,则它可能已更改并导致抛出此异常。

You need to use a temporary songs list and create a new adapter with it to update your list, thus not changing the current adapter list until you set a new adapter from the main UI thread. 您需要使用临时歌曲列表并创建一个新的适配器来更新列表,因此,除非您从主UI线程设置了新的适配器,否则不要更改当前的适配器列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM