title: HOW TO ADD TOAST MESSAGE IN onComplete,I am a begginer in Android Studio and I do not much know about java
body: <p>I want to show Toast message in my app after finishing the downloading. I took the code on the internet and it works like this:- the app is downloading the video from the server and after that, it adds my own watermark in the video, it works nicely but now I  want to show TOAST message after finishing the adding watermark thing. I add a simple Toast code but after finishing the watermark processing app but it automatically closes because of the simple Toast message, so anyone help to fix his coding problem, if you need any additional info than this, then let me know.</p>
  
  <p><strong>THIS IS THE WHOLE CODE OF MY JAVA CLASS</strong></p>
  
  <p>public class DownloadService extends Service {</p>
  
  <pre><code>private DatabaseHandler db;
  private NotificationCompat.Builder myNotify;
  private String video_id, downloadUrl, file_path_delete, file_path, file_name, layout_type, watermark_image, watermark_on_off;
  private RemoteViews rv;
  private OkHttpClient client;
  private WaterMarkData waterMarkData;
  private GPUMp4Composer gpuMp4Composer;
  public static final String ACTION_STOP = "com.mydownload.action.STOP";
  public static final String ACTION_START = "com.mydownload.action.START";
  private String NOTIFICATION_CHANNEL_ID = "download_ch_1";
  private static final String CANCEL_TAG = "c_tag";
  NotificationManager mNotificationManager;
  private boolean isWaterMark = false;
  private boolean isResize = false;
  
  
  private Handler mHandler = new Handler(new Handler.Callback() {
      @Override
      public boolean handleMessage(Message message) {
          int progress = Integer.parseInt(message.obj.toString());
          switch (message.what) {
              case 1:
                  rv.setTextViewText(R.id.nf_title, getString(R.string.app_name));
                  rv.setProgressBar(R.id.progress, 100, progress, false);
                  if (isWaterMark) {
                      rv.setTextViewText(R.id.nf_percentage, getResources().getString(R.string.watermark) + " " + "(" + progress + " %)");
                  } else {
                      rv.setTextViewText(R.id.nf_percentage, getResources().getString(R.string.downloading) + " " + "(" + progress + " %)");
                  }
                  myNotify.setCustomContentView(rv);
                  startForeground(1002, myNotify.build());
                  break;
              case 2:
                  stopForeground(true);
                  stopSelf();
                  break;
          }
          return false;
      }
  });
  
  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
      return null;
  }
  
  @Override
  public void onCreate() {
      super.onCreate();
  
      db = new DatabaseHandler(getApplicationContext());
  
      mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      myNotify = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
      myNotify.setChannelId(NOTIFICATION_CHANNEL_ID);
      myNotify.setSmallIcon(R.mipmap.ic_launcher);
      myNotify.setTicker(getResources().getString(R.string.downloading));
      myNotify.setWhen(System.currentTimeMillis());
      myNotify.setOnlyAlertOnce(true);
  
      rv = new RemoteViews(getPackageName(),
              R.layout.my_custom_notification);
      rv.setTextViewText(R.id.nf_title, getString(R.string.app_name));
      rv.setProgressBar(R.id.progress, 100, 0, false);
      rv.setTextViewText(R.id.nf_percentage, getResources().getString(R.string.downloading) + " " + "(0%)");
  
      Intent closeIntent = new Intent(this, DownloadService.class);
      closeIntent.setAction(ACTION_STOP);
      PendingIntent pcloseIntent = PendingIntent.getService(this, 0,
              closeIntent, 0);
      rv.setOnClickPendingIntent(R.id.nf_close, pcloseIntent);
  
      myNotify.setCustomContentView(rv);
      NotificationChannel mChannel;
      if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {
          CharSequence name = "Online Channel download";// The user-visible name of the channel.
          mChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, NotificationManager.IMPORTANCE_HIGH);
          mNotificationManager.createNotificationChannel(mChannel);
      }
      startForeground(1002, myNotify.build());
  }
  
  @Override
  public void onDestroy() {
      super.onDestroy();
      stopForeground(true);
  }
  
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      super.onStartCommand(intent, flags, startId);
      if (intent.getAction() != null &amp;&amp; intent.getAction().equals(ACTION_START)) {
          video_id = intent.getStringExtra("video_id");
          downloadUrl = intent.getStringExtra("downloadUrl");
          file_path = intent.getStringExtra("file_path");
          file_name = intent.getStringExtra("file_name");
          layout_type = intent.getStringExtra("layout_type");
          watermark_image = intent.getStringExtra("watermark_image");
          watermark_on_off = intent.getStringExtra("watermark_on_off");
  
          assert watermark_on_off != null;
          if (watermark_on_off.equals("true")) {
              file_path = getExternalCacheDir().getAbsolutePath();
          }
  
  
          file_path_delete = file_path;
  
          init();
      }
      if (intent.getAction() != null &amp;&amp; intent.getAction().equals(ACTION_STOP)) {
          stopForeground(true);
          stopSelf();
          if (gpuMp4Composer != null) {
              gpuMp4Composer.cancel();
          }
          if (waterMarkData != null) {
              waterMarkData.cancel(true);
          }
          if (!db.checkId_video_download(video_id)) {
              db.delete_video_download(video_id);
          }
          File file = new File(file_path_delete, file_name);
          if (file.exists()) {
              file.delete();
          }
          Method.isDownload = true;
          if (client != null) {
              for (Call call : client.dispatcher().runningCalls()) {
                  if (call.request().tag().equals(CANCEL_TAG))
                      call.cancel();
              }
          }
      }
      return START_STICKY;
  }
  
  
  public void init() {
      new Thread(new Runnable() {
          @Override
          public void run() {
  
              client = new OkHttpClient();
              Request.Builder builder = new Request.Builder()
                      .url(downloadUrl)
                      .addHeader("Accept-Encoding", "identity")
                      .get()
                      .tag(CANCEL_TAG);
  
              Call call = client.newCall(builder.build());
  
              call.enqueue(new Callback() {
                  @Override
                  public void onFailure(@NonNull Call call, @NonNull IOException e) {
                      Log.e("TAG", "=============onFailure===============");
                      e.printStackTrace();
                      Log.d("error_downloading", e.toString());
                      Method.isDownload = true;
                  }
  
                  @Override
                  public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                      Log.e("TAG", "=============onResponse===============");
                      Log.e("TAG", "request headers:" + response.request().headers());
                      Log.e("TAG", "response headers:" + response.headers());
                      assert response.body() != null;
                      final ResponseBody responseBody = ProgressHelper.withProgress(response.body(), new ProgressUIListener() {
  
                          //if you don't need this method, don't override this methd. It isn't an abstract method, just an empty method.
                          @Override
                          public void onUIProgressStart(long totalBytes) {
                              super.onUIProgressStart(totalBytes);
                              Log.e("TAG", "onUIProgressStart:" + totalBytes);
                              Toast.makeText(getApplicationContext(), getResources().getString(R.string.downloading), Toast.LENGTH_SHORT).show();
                          }
  
                          @Override
                          public void onUIProgressChanged(long numBytes, long totalBytes, float percent, float speed) {
                              Log.e("TAG", "=============start===============");
                              Log.e("TAG", "numBytes:" + numBytes);
                              Log.e("TAG", "totalBytes:" + totalBytes);
                              Log.e("TAG", "percent:" + percent);
                              Log.e("TAG", "speed:" + speed);
                              Log.e("TAG", "============= end ===============");
                              Message msg = mHandler.obtainMessage();
                              msg.what = 1;
                              msg.obj = (int) (100 * percent) + "";
                              mHandler.sendMessage(msg);
                          }
  
                          //if you don't need this method, don't override this method. It isn't an abstract method, just an empty method.
                          @Override
                          public void onUIProgressFinish() {
                              super.onUIProgressFinish();
                              Log.e("TAG", "onUIProgressFinish:");
  
                              if (watermark_on_off.equals("true")) {
  
                                  //call data watermark class add to watermark
                                  waterMarkData = new WaterMarkData();
                                  waterMarkData.execute();
  
                              } else {
                                  Message msg = mHandler.obtainMessage();
                                  msg.what = 2;
                                  msg.obj = 0 + "";
                                  mHandler.sendMessage(msg);
                                  Method.isDownload = true;
                                  showMedia(file_path, file_name);
                              }
  
                          }
                      });
  
  
                      try {
  
                          BufferedSource source = responseBody.source();
                          File outFile = new File(file_path + "/" + file_name);
                          BufferedSink sink = Okio.buffer(Okio.sink(outFile));
                          source.readAll(sink);
                          sink.flush();
                          source.close();
  
                      } catch (Exception e) {
                          Log.d("show_data", e.toString());
                      }
  
                  }
              });
          }
      }).start();
  }
  
  @SuppressLint("StaticFieldLeak")
  class WaterMarkData extends AsyncTask&lt;String, String, String&gt; {
  
      @Override
      protected String doInBackground(String... strings) {
  
          //check water mark on or off
          MediaPlayer mp = new MediaPlayer();
          try {
              mp.setDataSource(downloadUrl);
              mp.prepareAsync();
              mp.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
                  @Override
                  public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                      Log.d("call_data", "sizedata");
                      if (layout_type.equals("Portrait")) {
                          if (height &lt;= 700) {
                              isResize = true;
                          }
                      } else {
                          if (height &lt;= 400 || width &lt;= 400) {
                              isResize = true;
                          }
                      }
                      watermark();//call method water mark adding
                  }
              });
          } catch (IllegalArgumentException e) {
              e.printStackTrace();
              watermark();//call method water mark adding
              Log.d("call_data", "error");
          } catch (SecurityException e) {
              e.printStackTrace();
              watermark();//call method water mark adding
              Log.d("call_data", "error");
          } catch (IllegalStateException e) {
              e.printStackTrace();
              watermark();//call method water mark adding
              Log.d("call_data", "error");
          } catch (IOException e) {
              e.printStackTrace();
              watermark();//call method water mark adding
              Log.d("call_data", "error");
          } catch (Exception e) {
              e.printStackTrace();
              watermark();//call method water mark adding
              Log.d("call_data", "error");
          }
  
          return null;
      }
  
      @Override
      protected void onPostExecute(String s) {
          super.onPostExecute(s);
          Log.d("data", "execute");
      }
  }
  
  private void watermark() {
  
      //check water mark on or off
  
      new Thread(new Runnable() {
          @Override
          public void run() {
              Bitmap image = null;
              try {
                  URL url = new URL(watermark_image);
                  try {
                      image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
                  } catch (Exception e) {
                      Log.d("error_data", e.toString());
                  }
              } catch (IOException e) {
                  Log.d("error", e.toString());
                  System.out.println(e);
                  image = BitmapFactory.decodeResource(getResources(), R.drawable.watermark);
              }
  
              if (isResize) {
                  image = getResizedBitmap(image, 40, 40);
                  isResize = false;
              }
  
              String destinationPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Latest_Video_Status/";
  
              file_path_delete = destinationPath;
  
              gpuMp4Composer = new GPUMp4Composer(file_path + "/" + file_name, destinationPath + file_name)
                      .filter(new GlWatermarkFilter(image, GlWatermarkFilter.Position.RIGHT_BOTTOM))
                      .listener(new GPUMp4Composer.Listener() {
                          @Override
                          public void onProgress(double progress) {
                              isWaterMark = true;
                              double value = progress * 100;
                              int i = (int) value;
                              Message msg = mHandler.obtainMessage();
                              msg.what = 1;
                              msg.obj = i + "";
                              mHandler.sendMessage(msg);
                              Log.d(TAG, "onProgress = " + progress);
                              Log.d("call_data", "watermark");
                          }
  
                          @Override
                          public void onCompleted() {
                              isWaterMark = false;
                              new File(getExternalCacheDir().getAbsolutePath() + "/" + file_name).delete();//delete file to save in cash folder
                              Message msg = mHandler.obtainMessage();
                              msg.what = 2;
                              msg.obj = 0 + "";
                              mHandler.sendMessage(msg);
                              Method.isDownload = true;
                              showMedia(destinationPath, file_name);
                              Log.d(TAG, "onCompleted()");
  
  
                              runOnUiThread(new Runnable()
                                    {
                                        @Override
                                        public void run() {
                                            Toast.makeText(getApplicationContext(), "Your text.",
                                                    Toast.LENGTH_SHORT).show();
                                        }
                                    }
                              );
  
                          }
  
                          @Override
                          public void onCanceled() {
                              isWaterMark = false;
                              Message msg = mHandler.obtainMessage();
                              msg.what = 2;
                              msg.obj = 0 + "";
                              mHandler.sendMessage(msg);
                              Method.isDownload = true;
                              Log.d(TAG, "onCanceled");
                          }
  
                          @Override
                          public void onFailed(Exception exception) {
                              isWaterMark = false;
                              Message msg = mHandler.obtainMessage();
                              msg.what = 2;
                              msg.obj = 0 + "";
                              mHandler.sendMessage(msg);
                              Method.isDownload = true;
                              Log.e(TAG, "onFailed()", exception);
                          }
                      })
                      .start();
          }
      }).start();
  
  }
  
  public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
      int width = bm.getWidth();
      int height = bm.getHeight();
      float scaleWidth = ((float) newWidth) / width;
      float scaleHeight = ((float) newHeight) / height;
      // CREATE A MATRIX FOR THE MANIPULATION
      Matrix matrix = new Matrix();
      // RESIZE THE BIT MAP
      matrix.postScale(scaleWidth, scaleHeight);
  
      // "RECREATE" THE NEW BITMAP
      Bitmap resizedBitmap = Bitmap.createBitmap(
              bm, 0, 0, width, height, matrix, false);
      bm.recycle();
      return resizedBitmap;
  }
  
  public void showMedia(String file_path, String file_name) {
      try {
          MediaScannerConnection.scanFile(getApplicationContext(), new String[]{file_path + "/" + file_name},
                  null,
                  new MediaScannerConnection.OnScanCompletedListener() {
                      @Override
                      public void onScanCompleted(String path, Uri uri) {
  
                      }
                  });
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p><strong>ERROR</strong></p>
  
  <pre><code>Can't toast on a thread that has not called Looper.prepare()
  </code></pre>
  
  <p>How what to do now to fix this issue, please anyone help me. </p>
  
  <p><strong>Solution</strong></p>
  
  <pre><code>     new Handler(Looper.getMainLooper()).post(new Runnable() {
                                  public void run() {
                                      Toast.makeText(getApplicationContext(), "KISHAN",
                                              Toast.LENGTH_SHORT).show();
                                  }
                              });
  </code></pre>