Android在主线程上工作太多了

时间:2017-04-13 12:53:47

标签: android multithreading android-asynctask

我正在创建一个MP3播放器应用程序作为辅助项目。

我有一项名为" AddPlaylistActivity"它处理从手机本地存储上可用的所有歌曲创建和添加播放列表。如果我不尝试一次将很多歌曲添加到同一个播放列表,它的工作正常。它处理< 15 fine,但是> 20-ish并且崩溃完全在日志中声明在主线程上可能有太多工作要做。

我已经尝试创建一个新线程来保存在UI线程上运行的播放列表,因为这是唯一允许的方式,因为否则我得到红色警告,必须在主线程上执行操作。

我也试过运行一个UI线程,然后运行另一个" normal"处理播放列表添加的线程。

我的播放列表添加如下:

这里我有导航菜单,我可以点击"添加播放列表"打开添加播放列表活动。

@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
    int id = menuItem.getItemId();

    if (id == R.id.addPlaylist) {
        Intent intent = new Intent(MP3Player.this, AddPlaylistActivity.class);
        //startActivity(intent);
        startActivityForResult(intent, 1);
        return true;
    }
    else if (id == R.id.allSongs) {
        allSongs();
    }
    else {
        updateSongList(navigationView.indexOfChild(menuItem.getActionView()));
    }
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);

    return true;
}

在AddPlaylistActivity中,我有将歌曲添加到To-Be播放列表的功能。但是这段代码工作正常,我认为最有趣的部分是我用来返回一大堆歌曲的方法,回到主要活动:

public void createPlaylist(String playlistName, ArrayList<Song> newPlaylistSongsArray) {
    Intent returnIntent = new Intent();
    Bundle b = new Bundle();
    b.putSerializable("array", newPlaylistSongsArray);
    returnIntent.putExtra("playListName", playlistName);
    returnIntent.putExtras(b);
    setResult(Activity.RESULT_OK,returnIntent);
    finish();
}

此捆绑包被发送到onActivityResult方法,该方法接收捆绑包并将新播放列表的歌曲保存为新的播放列表&#34; file&#34;或手机上共享偏好设置中的数据。我想这更像是一个参考列表,哪些歌曲应该在哪个列表中。

@Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
    if (requestCode == 1) {
        if (resultCode == Activity.RESULT_OK) {
            String newPlaylistName = data.getStringExtra("playListName");
            Bundle b = data.getExtras();
            final PlayList newPlaylist = new PlayList();
            newPlaylist.setSongsInPlayList((ArrayList<Song>) b.getSerializable("array"));
            newPlaylist.setPlayListName(newPlaylistName);

            /*
            When storing a new playlist, the next and previous song references
            needs to be nulled in order for them to be able to be saved in the
            preferences.
            These next and prev references are restored when a playlist is loaded
            again from the preferences.
             */
            for (Song s : newPlaylist.getSongsInPlayList()) {
                s.setNext(null);
                s.setPrev(null);
            }

            /*
            Add the new playlist to the navigation view and give it an icon
            and a click listener.
             */
            MenuItem newPlaylistItem = navigationMenu.add(newPlaylistName);
            newPlaylistItem.setIcon((ResourcesCompat.getDrawable(getResources(), android.R.drawable.ic_menu_save, null)));
            navigationView.setNavigationItemSelectedListener(MP3Player.this);

            /*
            Now, store the new playlist in the shared preferences.
             */
            SharedPreferences.Editor prefsEditor = prefs.edit();
            Gson gson = new Gson();

            prefsEditor.putString("PLAYLISTS", null);
            prefsEditor.apply();

            ArrayList<PlayList> playListsInMenu;
            String playlistString = prefs.getString("PLAYLISTS", null);
            /*
            Check shared prefs for existing playlists.w
             */
            if (playlistString == null) {
                playListsInMenu = new ArrayList<>();
                playListsInMenu.add(newPlaylist);
            } else {
                Type type = new TypeToken<ArrayList<PlayList>>() {
                }.getType();
                playListsInMenu = gson.fromJson(playlistString, type);
                playListsInMenu.add(newPlaylist);

            }
            String json = gson.toJson(playListsInMenu);
            prefsEditor.putString("PLAYLISTS", json);
            prefsEditor.apply();
            Toast.makeText(MP3Player.this, "New Playlist Created", Toast.LENGTH_LONG).show();
        }

        if (resultCode == Activity.RESULT_CANCELED) {
            Toast.makeText(MP3Player.this, "Shit went wrong yo!", Toast.LENGTH_LONG).show();
        }
    }
}

我不太确定导致崩溃的序列的哪一部分。我不认为它是createPlaylist,因为它只是将一个包返回给主要活动。我认为问题出在我的onActivityResult方法中,因为这里的包被解压缩,放到JSON格式并存储在共享的prefs中,而主线程仍处于运行状态并可以这么说。

我猜这是我的问题所在,但我不知道如何解决这个问题。

我也尝试过使用AsyncTask,但是为​​了使它工作,我必须使asyncTask类抽象,这样我就可以将我的Intent Data从onActivityResult传递给asynctask类并在其中执行操作。然而,这使我无法执行asynctasak,因为它不能是抽象的。

有没有人有任何建议或解决方法?

0 个答案:

没有答案