这个AsyncTask类应该是静态的,否则可能会通过YouTubeExtractor泄漏

时间:2019-04-12 23:35:08

标签: java android android-asynctask static

我正在使用Youtube Extractor library

implementation 'com.github.HaarigerHarald:android-youtubeExtractor:master-SNAPSHOT'

我正在使用它来提取片段中的youtube下载网址,该网址提取完成后立即上传到我的Firebase数据库中

if (requestCode==0000 && resultCode==getActivity().RESULT_OK){

            if (videoPath != null ) {
                for (String s : videoPath) {

                    new YouTubeExtractor(context) { // THIS LIBRARY SHOWING WARNING
                        @Override
                        protected void onExtractionComplete(SparseArray<YtFile> ytFiles, VideoMeta videoMeta) {
                            if (ytFiles !=null){
                                int itag = 18;
                                String link = ytFiles.get(18).getUrl();

                                Map<String, Object> map = new HashMap<>();
                                map.put("Message", link);

                                String Temp_Key = databaseReference.push().getKey();
                                Map<String, Object> RoomKey = new HashMap<>();
                                databaseReference.updateChildren(RoomKey);
                                DatabaseReference message_Root = databaseReference.child(Temp_Key);
                                message_Root.updateChildren(map);

                            }
                        }

                    }.extract(s, true, true);

                }
            }

我的问题是如何使用该库解决此警告。我不想使用@SuppressLint("StaticFieldLeak"),它只会抑制警告而无法解决它。

2 个答案:

答案 0 :(得分:0)

为避免内存泄漏,您需要在AsyncTask中创建对活动/片段的一周引用; here通过下面的代码示例对此进行了完整的解释

public class MyActivity extends AppCompatActivity {

int mSomeMemberVariable = 123;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // start the AsyncTask, passing the Activity context
    // in to a custom constructor 
    new MyTask(this).execute();
}

private static class MyTask extends AsyncTask<Void, Void, String> {

    private WeakReference<MyActivity> activityReference;

    // only retain a weak reference to the activity 
    MyTask(MyActivity context) {
        activityReference = new WeakReference<>(context);
    }

    @Override
    protected String doInBackground(Void... params) {

        // do some long running task...

        return "task finished";
    }

    @Override
    protected void onPostExecute(String result) {

        // get a reference to the activity if it is still there
        MyActivity activity = activityReference.get();
        if (activity == null || activity.isFinishing()) return;

        // modify the activity's UI
        TextView textView = activity.findViewById(R.id.textview);
        textView.setText(result);

        // access Activity member variables
        activity.mSomeMemberVariable = 321;
    }
}

}

AsyncTask还具有其他替代方案,例如ExecutorAsyncTaskLoader,您可能会想到它们。希望这会有所帮助。

答案 1 :(得分:0)

YouTubeExtractor已经在后台使用了WeakReference,以避免泄漏您的上下文(活动,服务等)。因此,您可以使用@SuppressLint("StaticFieldLeak")删除警告。

还有另一种解决方案是创建一个从YouTubeExtractor扩展的类。

static class MyYoutubeExtractor extends YouTubeExtractor {
    MyYoutubeExtractor(@NonNull Context con) {
        super(con);
    }

    @Override
    protected void onExtractionComplete(SparseArray<YtFile> ytFiles, VideoMeta videoMeta) {
        if (ytFiles != null) {
            int itag = 18;
            String link = ytFiles.get(18).getUrl();

            Map<String, Object> map = new HashMap<>();
            map.put("Message", link);

            String Temp_Key = databaseReference.push().getKey();
            Map<String, Object> RoomKey = new HashMap<>();
            databaseReference.updateChildren(RoomKey);
            DatabaseReference message_Root = databaseReference.child(Temp_Key);
            message_Root.updateChildren(map);
        }
    }
}

然后使用它

new MyYoutubeExtractor(context).extract("", true, true);