【问题标题】:This AsyncTask class should be static or leaks might occur via YouTubeExtractor此 AsyncTask 类应该是静态的,否则可能会通过 YouTubeExtractor 发生泄漏
【发布时间】:2019-09-03 18:03:30
【问题描述】:

我正在使用Youtube Extractor library

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

我正在使用它在我的片段中获取 YouTube 下载 URL,一旦它完成提取就会上传到我的 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"),它只会抑制警告而不是解决它。

【问题讨论】:

  • 好吧,如果 AsyncTask 没有声明为静态的,它可能会导致泄漏,因为它不支持生命周期。因此,例如,当您旋转设备时,如果您不手动销毁任务,它可能会保留对已销毁对象的引用,从而导致泄漏。如果你想解决这个问题,你需要将 AsyncTask 设为静态。
  • @T.Mas 因为我正在使用这个库,所以我无法提供它WeakReference。也不能修改库方法。任何解决方案

标签: java android android-asynctask static


【解决方案1】:

为避免内存泄漏,您需要在 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,您可能会想到它们。希望这会有所帮助。

【讨论】:

  • 感谢您的回答,但我无法修改库,并且我尝试分配弱引用,但它根本不起作用
  • @Ritu;我只是在自己的项目中遇到了这个问题;刚刚通过将 AsyncTask 与活动隔离并利用 MVVM 模式与架构组件(实时数据)来解决它;我将自定义的 AsycnTask 放入存储库。然后将其设为静态,一切就绪……所以尝试从异步任务中提取任何更新 UI 的代码,并让它抓取 API 数据; LiveData 将完成剩下的工作
猜你喜欢
  • 2017-11-02
  • 2020-10-30
  • 2013-09-22
  • 2012-07-09
  • 1970-01-01
  • 2012-11-10
  • 2013-08-14
相关资源
最近更新 更多