diff --git a/app/src/main/java/org/schabi/newpipe/download/DeleteManager.java b/app/src/main/java/org/schabi/newpipe/download/DeleteManager.java
new file mode 100644
index 000000000..210cf668d
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/download/DeleteManager.java
@@ -0,0 +1,178 @@
+package org.schabi.newpipe.download;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.design.widget.BaseTransientBottomBar;
+import android.support.design.widget.Snackbar;
+import android.view.View;
+
+import org.schabi.newpipe.R;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import io.reactivex.Completable;
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+import io.reactivex.subjects.PublishSubject;
+import us.shandian.giga.get.DownloadManager;
+import us.shandian.giga.get.DownloadMission;
+
+public class DeleteManager {
+
+    private static final String KEY_STATE = "delete_manager_state";
+
+    private View mView;
+    private HashSet<String> mPendingMap;
+    private List<Disposable> mDisposableList;
+    private DownloadManager mDownloadManager;
+    private PublishSubject<DownloadMission> publishSubject = PublishSubject.create();
+
+    DeleteManager(Activity activity) {
+        mPendingMap = new HashSet<>();
+        mDisposableList = new ArrayList<>();
+        mView = activity.findViewById(android.R.id.content);
+    }
+
+    public Observable<DownloadMission> getUndoObservable() {
+        return publishSubject;
+    }
+
+    public boolean contains(@NonNull DownloadMission mission) {
+        return mPendingMap.contains(mission.url);
+    }
+
+    public void add(@NonNull DownloadMission mission) {
+        mPendingMap.add(mission.url);
+
+        if (mPendingMap.size() == 1) {
+            showUndoDeleteSnackbar(mission);
+        }
+    }
+
+    public void setDownloadManager(@NonNull DownloadManager downloadManager) {
+        mDownloadManager = downloadManager;
+
+        if (mPendingMap.size() < 1) {
+            //nothing to do
+            return;
+        }
+
+        showUndoDeleteSnackbar();
+    }
+
+    public void restoreState(@Nullable Bundle savedInstanceState) {
+        if (savedInstanceState == null) {
+            // nothing to do
+            return;
+        }
+
+        List<String> list = savedInstanceState.getStringArrayList(KEY_STATE);
+        if (list != null) {
+            mPendingMap.addAll(list);
+        }
+    }
+
+    public void saveState(@Nullable Bundle outState) {
+        if (outState == null) {
+            // nothing to do
+            return;
+        }
+
+        for (Disposable disposable : mDisposableList) {
+            disposable.dispose();
+        }
+
+        outState.putStringArrayList(KEY_STATE, new ArrayList<>(mPendingMap));
+    }
+
+    private void showUndoDeleteSnackbar() {
+        if (mPendingMap.size() < 1) {
+            // nothing to do
+            return;
+        }
+
+        String url = mPendingMap.iterator().next();
+
+        for (int i = 0; i < mDownloadManager.getCount(); i++) {
+            DownloadMission mission = mDownloadManager.getMission(i);
+            if (url.equals(mission.url)) {
+                showUndoDeleteSnackbar(mission);
+                break;
+            }
+        }
+    }
+
+    private void showUndoDeleteSnackbar(@NonNull DownloadMission mission) {
+        final Snackbar snackbar = Snackbar.make(mView, mission.name, Snackbar.LENGTH_INDEFINITE);
+        final Disposable disposable = Observable.timer(3, TimeUnit.SECONDS)
+                .subscribeOn(AndroidSchedulers.mainThread())
+                .subscribe(l -> snackbar.dismiss());
+
+        mDisposableList.add(disposable);
+
+        snackbar.setAction(R.string.undo, v -> {
+            mPendingMap.remove(mission.url);
+            publishSubject.onNext(mission);
+            disposable.dispose();
+            snackbar.dismiss();
+        });
+
+        snackbar.addCallback(new BaseTransientBottomBar.BaseCallback<Snackbar>() {
+            @Override
+            public void onDismissed(Snackbar transientBottomBar, int event) {
+                if (!disposable.isDisposed()) {
+                    mPendingMap.remove(mission.url);
+                    Completable.fromAction(() -> deletePending(mission))
+                            .subscribeOn(Schedulers.io())
+                            .subscribe();
+                }
+                snackbar.removeCallback(this);
+                mDisposableList.remove(disposable);
+                showUndoDeleteSnackbar();
+            }
+        });
+
+        snackbar.show();
+    }
+
+    public void deletePending() {
+        if (mPendingMap.size() < 1) {
+            // nothing to do
+            return;
+        }
+
+        HashSet<Integer> idSet = new HashSet<>();
+        for (int i = 0; i < mDownloadManager.getCount(); i++) {
+            if (contains(mDownloadManager.getMission(i))) {
+                idSet.add(i);
+            }
+        }
+
+        for (Integer id : idSet) {
+            mDownloadManager.deleteMission(id);
+        }
+
+        mPendingMap.clear();
+    }
+
+    private void deletePending(@NonNull DownloadMission mission) {
+        if (!contains(mission)) {
+            // nothing to do
+            return;
+        }
+
+        for (int i = 0; i < mDownloadManager.getCount(); i++) {
+            if (mission.url.equals(mDownloadManager.getMission(i).url)) {
+                mDownloadManager.deleteMission(i);
+                break;
+            }
+        }
+    }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadActivity.java b/app/src/main/java/org/schabi/newpipe/download/DownloadActivity.java
index 6512f5270..f9c48a533 100644
--- a/app/src/main/java/org/schabi/newpipe/download/DownloadActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/download/DownloadActivity.java
@@ -15,12 +15,17 @@ import org.schabi.newpipe.R;
 import org.schabi.newpipe.settings.SettingsActivity;
 import org.schabi.newpipe.util.ThemeHelper;
 
+import io.reactivex.Completable;
+import io.reactivex.schedulers.Schedulers;
 import us.shandian.giga.service.DownloadManagerService;
 import us.shandian.giga.ui.fragment.AllMissionsFragment;
 import us.shandian.giga.ui.fragment.MissionsFragment;
 
 public class DownloadActivity extends AppCompatActivity {
 
+    private static final String MISSIONS_FRAGMENT_TAG = "fragment_tag";
+    private DeleteManager mDeleteManager;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         // Service
@@ -42,21 +47,35 @@ public class DownloadActivity extends AppCompatActivity {
             actionBar.setDisplayShowTitleEnabled(true);
         }
 
-        // Fragment
-        getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
-            @Override
-            public void onGlobalLayout() {
-                updateFragments();
-                getWindow().getDecorView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
-            }
-        });
+        mDeleteManager = new DeleteManager(this);
+        mDeleteManager.restoreState(savedInstanceState);
+
+        MissionsFragment fragment = (MissionsFragment) getFragmentManager().findFragmentByTag(MISSIONS_FRAGMENT_TAG);
+        if (fragment != null) {
+            fragment.setDeleteManager(mDeleteManager);
+        } else {
+            getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+                @Override
+                public void onGlobalLayout() {
+                    updateFragments();
+                    getWindow().getDecorView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
+                }
+            });
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        mDeleteManager.saveState(outState);
+        super.onSaveInstanceState(outState);
     }
 
     private void updateFragments() {
-
         MissionsFragment fragment = new AllMissionsFragment();
+        fragment.setDeleteManager(mDeleteManager);
+
         getFragmentManager().beginTransaction()
-                .replace(R.id.frame, fragment)
+                .replace(R.id.frame, fragment, MISSIONS_FRAGMENT_TAG)
                 .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
                 .commit();
     }
@@ -80,6 +99,7 @@ public class DownloadActivity extends AppCompatActivity {
             case R.id.action_settings: {
                 Intent intent = new Intent(this, SettingsActivity.class);
                 startActivity(intent);
+                deletePending();
                 return true;
             }
             default:
@@ -87,4 +107,15 @@ public class DownloadActivity extends AppCompatActivity {
         }
     }
 
+    @Override
+    public void onBackPressed() {
+        super.onBackPressed();
+        deletePending();
+    }
+
+    private void deletePending() {
+        Completable.fromAction(mDeleteManager::deletePending)
+                .subscribeOn(Schedulers.io())
+                .subscribe();
+    }
 }
diff --git a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java
index 12c81c127..4054c8a15 100644
--- a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java
+++ b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java
@@ -25,10 +25,13 @@ import android.widget.TextView;
 import android.widget.Toast;
 
 import org.schabi.newpipe.R;
+import org.schabi.newpipe.download.DeleteManager;
 
 import java.io.File;
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
@@ -52,18 +55,34 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
 
     private Activity mContext;
     private LayoutInflater mInflater;
-    private DownloadManager mManager;
+    private DownloadManager mDownloadManager;
+    private DeleteManager mDeleteManager;
+    private List<DownloadMission> mItemList;
     private DownloadManagerService.DMBinder mBinder;
     private int mLayout;
 
-    public MissionAdapter(Activity context, DownloadManagerService.DMBinder binder, DownloadManager manager, boolean isLinear) {
+    public MissionAdapter(Activity context, DownloadManagerService.DMBinder binder, DownloadManager downloadManager, DeleteManager deleteManager, boolean isLinear) {
         mContext = context;
-        mManager = manager;
+        mDownloadManager = downloadManager;
+        mDeleteManager = deleteManager;
         mBinder = binder;
 
         mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
         mLayout = isLinear ? R.layout.mission_item_linear : R.layout.mission_item;
+
+        mItemList = new ArrayList<>();
+        updateItemList();
+    }
+
+    public void updateItemList() {
+        mItemList.clear();
+
+        for (int i = 0; i < mDownloadManager.getCount(); i++) {
+            DownloadMission mission = mDownloadManager.getMission(i);
+            if (!mDeleteManager.contains(mission)) {
+                mItemList.add(mDownloadManager.getMission(i));
+            }
+        }
     }
 
     @Override
@@ -102,7 +121,7 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
 
     @Override
     public void onBindViewHolder(MissionAdapter.ViewHolder h, int pos) {
-        DownloadMission ms = mManager.getMission(pos);
+        DownloadMission ms = mItemList.get(pos);
         h.mission = ms;
         h.position = pos;
 
@@ -123,7 +142,7 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
 
     @Override
     public int getItemCount() {
-        return mManager.getCount();
+        return mItemList.size();
     }
 
     @Override
@@ -214,12 +233,12 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
                 int id = item.getItemId();
                 switch (id) {
                     case R.id.start:
-                        mManager.resumeMission(h.position);
-                        mBinder.onMissionAdded(mManager.getMission(h.position));
+                        mDownloadManager.resumeMission(h.position);
+                        mBinder.onMissionAdded(mItemList.get(h.position));
                         return true;
                     case R.id.pause:
-                        mManager.pauseMission(h.position);
-                        mBinder.onMissionRemoved(mManager.getMission(h.position));
+                        mDownloadManager.pauseMission(h.position);
+                        mBinder.onMissionRemoved(mItemList.get(h.position));
                         h.lastTimeStamp = -1;
                         h.lastDone = -1;
                         return true;
@@ -245,12 +264,13 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
 
                         return true;
                     case R.id.delete:
-                        mManager.deleteMission(h.position);
+                        mDeleteManager.add(h.mission);
+                        updateItemList();
                         notifyDataSetChanged();
                         return true;
                     case R.id.md5:
                     case R.id.sha1:
-                        DownloadMission mission = mManager.getMission(h.position);
+                        DownloadMission mission = mItemList.get(h.position);
                         new ChecksumTask(mContext).execute(mission.location + "/" + mission.name, ALGORITHMS.get(id));
                         return true;
                     default:
@@ -262,19 +282,6 @@ public class MissionAdapter extends RecyclerView.Adapter<MissionAdapter.ViewHold
         popup.show();
     }
 
-    private void viewFile(File file, String mimetype) {
-        Intent intent = new Intent();
-        intent.setAction(Intent.ACTION_VIEW);
-        intent.setDataAndType(Uri.fromFile(file), mimetype);
-        intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            intent.addFlags(FLAG_GRANT_PREFIX_URI_PERMISSION);
-        }
-        //mContext.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        Log.v(TAG, "Starting intent: " + intent);
-        mContext.startActivity(intent);
-    }
-
     private void viewFileWithFileProvider(File file, String mimetype) {
         String ourPackage = mContext.getApplicationContext().getPackageName();
         Uri uri = FileProvider.getUriForFile(mContext, ourPackage + ".provider", file);
diff --git a/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java b/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java
index 2ff83086f..bf5a82c0e 100644
--- a/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java
+++ b/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java
@@ -10,6 +10,8 @@ import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
@@ -19,13 +21,17 @@ import android.view.View;
 import android.view.ViewGroup;
 
 import org.schabi.newpipe.R;
+import org.schabi.newpipe.download.DeleteManager;
 
+import io.reactivex.disposables.Disposable;
+import io.reactivex.functions.Consumer;
 import us.shandian.giga.get.DownloadManager;
+import us.shandian.giga.get.DownloadMission;
 import us.shandian.giga.service.DownloadManagerService;
 import us.shandian.giga.ui.adapter.MissionAdapter;
 
 public abstract class MissionsFragment extends Fragment {
-    private DownloadManager mManager;
+    private DownloadManager mDownloadManager;
     private DownloadManagerService.DMBinder mBinder;
 
     private SharedPreferences mPrefs;
@@ -37,14 +43,19 @@ public abstract class MissionsFragment extends Fragment {
     private GridLayoutManager mGridManager;
     private LinearLayoutManager mLinearManager;
     private Context mActivity;
+    private DeleteManager mDeleteManager;
+    private Disposable mDeleteDisposable;
 
     private ServiceConnection mConnection = new ServiceConnection() {
 
         @Override
         public void onServiceConnected(ComponentName name, IBinder binder) {
             mBinder = (DownloadManagerService.DMBinder) binder;
-            mManager = setupDownloadManager(mBinder);
-            updateList();
+            mDownloadManager = setupDownloadManager(mBinder);
+            if (mDeleteManager != null) {
+                mDeleteManager.setDownloadManager(mDownloadManager);
+                updateList();
+            }
         }
 
         @Override
@@ -55,6 +66,14 @@ public abstract class MissionsFragment extends Fragment {
 
     };
 
+    public void setDeleteManager(@NonNull DeleteManager deleteManager) {
+        mDeleteManager = deleteManager;
+        if (mDownloadManager != null) {
+            mDeleteManager.setDownloadManager(mDownloadManager);
+            updateList();
+        }
+    }
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         View v = inflater.inflate(R.layout.missions, container, false);
@@ -104,10 +123,26 @@ public abstract class MissionsFragment extends Fragment {
         mActivity = activity;
     }
 
+    @Override
+    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        if (mDeleteManager != null) {
+            mDeleteDisposable = mDeleteManager.getUndoObservable().subscribe(mission -> {
+                if (mAdapter != null) {
+                    mAdapter.updateItemList();
+                    mAdapter.notifyDataSetChanged();
+                }
+            });
+        }
+    }
+
     @Override
     public void onDestroyView() {
         super.onDestroyView();
         getActivity().unbindService(mConnection);
+        if (mDeleteDisposable != null) {
+            mDeleteDisposable.dispose();
+        }
     }
 
     @Override
@@ -129,7 +164,7 @@ public abstract class MissionsFragment extends Fragment {
     }
 
     private void updateList() {
-        mAdapter = new MissionAdapter((Activity) mActivity, mBinder, mManager, mLinear);
+        mAdapter = new MissionAdapter((Activity) mActivity, mBinder, mDownloadManager, mDeleteManager, mLinear);
 
         if (mLinear) {
             mList.setLayoutManager(mLinearManager);
@@ -143,7 +178,7 @@ public abstract class MissionsFragment extends Fragment {
             mSwitch.setIcon(mLinear ? R.drawable.grid : R.drawable.list);
         }
 
-        mPrefs.edit().putBoolean("linear", mLinear).commit();
+        mPrefs.edit().putBoolean("linear", mLinear).apply();
     }
 
     protected abstract DownloadManager setupDownloadManager(DownloadManagerService.DMBinder binder);