Cách gọi một phương thức sau khi trì hoãn trong Android


770

Tôi muốn có thể gọi phương thức sau đây sau một độ trễ xác định. Trong mục tiêu c có một cái gì đó như:

[self performSelector:@selector(DoSomething) withObject:nil afterDelay:5];

Có tương đương với phương pháp này trong Android với java không? Ví dụ tôi cần có thể gọi một phương thức sau 5 giây.

public void DoSomething()
{
     //do something here
}

Câu trả lời:


1859

Kotlin

Handler().postDelayed({
  //Do something after 100ms
}, 100)


Java

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
  @Override
  public void run() {
    //Do something after 100ms
  }
}, 100);



109
Giải pháp này chỉ hữu ích trên luồng UI. Mặt khác, trên luồng bình thường, bạn cần triển khai looper không phải là phiên bản tốt nhất tôi nghĩ
olivier_sdg

2
@olivier_sdg tại sao bạn cần triển khai looper?
djechlin

37
@djechlin Trình xử lý phải luôn được liên kết với Looper, điều này thực sự sẽ xử lý Runnable mà bạn đăng (). Chuỗi UI đã đi kèm với Looper, vì vậy bạn chỉ cần tạo Handler () mới trên luồng UI và đăng () Runnables trực tiếp lên nó. Những Runnables thực thi trên luồng UI. Để Runnables thực thi trên một luồng khác, bạn cần tạo một luồng mới, sau đó Looper.prepare (), tạo Handler mới () và sau đó là Looper.loop (). Bất kỳ Runnables nào được đăng lên Handler mới này sẽ thực thi trên luồng mới này. Nếu bạn không làm tất cả điều này, bài đăng () sẽ đưa ra một ngoại lệ.
Dororo

12
Trong trường hợp bạn cần, bạn cũng có thể hủy thực thi miễn là Runnable vẫn còn trong hàng đợi tin nhắn bằng cách gọi removeCallbacks(Runnable r)vào Handler.
Dennis

9
nênimport android.os.handler
KaKa

322

Tôi không thể sử dụng bất kỳ câu trả lời nào khác trong trường hợp của mình. Tôi đã sử dụng java Timer thay thế.

new Timer().schedule(new TimerTask() {          
    @Override
    public void run() {
        // this code will be executed after 2 seconds       
    }
}, 2000);

43
cái này tốt hơn những cái sử dụng Handler, vì nó không có vấn đề về Looper khi Handler không chạy trên luồng UI.
Ben H

32
Bạn nên giữ một tham chiếu đến bộ hẹn giờ của mình để hủy bỏ nó khi không cần thiết nữa vì theo tài liệu Android: "Khi không cần bộ hẹn giờ nữa, người dùng nên gọi hủy (), giải phóng luồng của bộ hẹn giờ và các tài nguyên khác. Bộ hẹn giờ không bị hủy rõ ràng có thể giữ tài nguyên vô thời hạn. "
Pooks

14
Chú ý! Điều này không chạy trên luồng UI. Chạy điều này trên luồng ui gây ra Lỗi nghiêm trọng: android.view.ViewRootImpl $ CalledFromWrongThreadException: Chỉ chủ đề ban đầu tạo phân cấp chế độ xem mới có thể chạm vào chế độ xem của nó.
vovahost

13
@vovahost chỉ vì bạn đang cập nhật các thành phần UI bên trong khối hẹn giờ
Tim

10
Lưu ý rằng java.util.Timer (và TimerTask) sẽ không được dùng trong JDK 9. TimerTask tạo Chủ đề mới cho các tác vụ không tốt lắm.
Varvara Kalinina

183

Lưu ý: Câu trả lời này được đưa ra khi câu hỏi không chỉ định Android làm bối cảnh. Để biết câu trả lời cụ thể cho chuỗi giao diện người dùng Android, hãy xem tại đây.


Có vẻ như API Mac OS cho phép luồng hiện tại tiếp tục và lên lịch tác vụ để chạy không đồng bộ. Trong Java, hàm tương đương được cung cấp bởi java.util.concurrentgói. Tôi không chắc chắn những hạn chế mà Android có thể áp đặt.

private static final ScheduledExecutorService worker = 
  Executors.newSingleThreadScheduledExecutor();

void someMethod() {
  
  Runnable task = new Runnable() {
    public void run() {
      /* Do something… */
    }
  };
  worker.schedule(task, 5, TimeUnit.SECONDS);
  
}

3
Này không bao giờ gọi Runnable đối với tôi
Supuhstar

14
Như một lưu ý phụ: Điều này cũng cho phép bạn hủy tác vụ sau, điều này có thể hữu ích trong một số tình huống. Đơn giản chỉ cần lưu trữ một tham chiếu đến ScheduledFuture<?>trả về bởi worker.schedule()và gọi cancel(boolean)phương thức của nó .
Dennis

Tôi nghĩ rằng câu trả lời này đã lỗi thời. .schedule dường như không còn là một phương pháp của Runnable nữa ...? : /
beetree

5
@beetree đó là một phương pháp trên ScheduledExecutorService.
erickson

3
Điều này không hoạt động nếu các đối tượng luồng ui có liên quan, bạn phải gọi runOnUIThread (new runnable () {run () ....}); hoặc đăng một runnable bằng cách sử dụng đối tượng xử lý từ bên trong run () {}
Jayant Arora

107

Để thực thi một cái gì đó trong UI Thread sau 5 giây:

new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something here
    }
}, 5000);

8
Xác nhận, đây là giải pháp tốt nhất để ngăn cuộc gọi đến looper.prepare và đặt toàn bộ nội dung vào luồng UI.
Tobliug 18/03/2015

Cảm ơn vì điều này, đã giúp tôi với các vấn đề về Looper :)
Tia

1
Tôi sẽ cẩn thận về việc tạo một trình xử lý trên bộ xử lý chính, sau đó trong chủ đề này, không có nhiệm vụ lâu dài nào được thực hiện
Shayan_Aryan

40

bạn có thể sử dụng Handler bên trong UIThread:

runOnUiThread(new Runnable() {

    @Override
    public void run() {
         final Handler handler = new Handler();
         handler.postDelayed(new Runnable() {
           @Override
           public void run() {
               //add your code here
           }
         }, 1000);

    }
});

36

Cảm ơn tất cả các câu trả lời tuyệt vời, tôi tìm thấy một giải pháp phù hợp nhất với nhu cầu của tôi.

Handler myHandler = new DoSomething();
Message m = new Message();
m.obj = c;//passing a parameter here
myHandler.sendMessageDelayed(m, 1000);

class DoSomething extends Handler {
    @Override
    public void handleMessage(Message msg) {
      MyObject o = (MyObject) msg.obj;
      //do something here
    }
}

Có ổn không nếu tôi sử dụng phương pháp này để có phản hồi cảm ứng khi nhấp vào một mục .. view.setColor (some_color) và sau đó xóa màu này trong Handler sau x giây ...?
eRaisedToX

25

Kotlin& JavaNhiều cách

1. Sử dụng Handler

Handler().postDelayed({
    TODO("Do something")
    }, 2000)

2. Sử dụng TimerTask

Timer().schedule(object : TimerTask() {
    override fun run() {
        TODO("Do something")
    }
}, 2000)

Hoặc thậm chí ngắn hơn

Timer().schedule(timerTask {
    TODO("Do something")
}, 2000)

Hoặc ngắn nhất sẽ là

Timer().schedule(2000) {
    TODO("Do something")
}

3. Sử dụng Executors

Executors.newSingleThreadScheduledExecutor().schedule({
    TODO("Do something")
}, 2, TimeUnit.SECONDS)

Trong Java

1. Sử dụng Handler

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something
    }
}, 2000);

2. Sử dụng Timer

new Timer().schedule(new TimerTask() {          
    @Override
    public void run() {
        // Do something
    }
}, 2000);

3. Sử dụng ScheduledExecutorService

private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();

Runnable runnable = new Runnable() {
  public void run() {
      // Do something
  }
  };
worker.schedule(runnable, 2, TimeUnit.SECONDS);

1
@JanRabe Cảm ơn lời đề nghị của bạn. Tôi đánh giá cao nó. Tuy nhiên câu hỏi là How to call a method after a delay in Android. Vì vậy, tôi tập trung vào đó. Đến điểm. Mặt khác, rò rỉ java là một chủ đề lớn để hiểu riêng cho các nhà phát triển.
Khemraj

20

Xem bản demo này:

import java.util.Timer;
import java.util.TimerTask;

class Test {
     public static void main( String [] args ) {
          int delay = 5000;// in ms 

          Timer timer = new Timer();

          timer.schedule( new TimerTask(){
             public void run() { 
                 System.out.println("Wait, what..:");
              }
           }, delay);

           System.out.println("Would it run?");
     }
}

20

Nếu bạn phải sử dụng Trình xử lý, nhưng bạn đang vào một luồng khác, bạn có thể sử dụng runonuithreadđể chạy trình xử lý trong luồng UI. Điều này sẽ cứu bạn khỏi Ngoại lệ ném yêu cầu gọiLooper.Prepare()

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //Do something after 1 second
            }
        }, 1000);
    }
});

Trông khá lộn xộn, nhưng đây là một trong những cách.


4
Điều này hoạt động, tôi không thể chỉnh sửa bài đăng của bạn vì quy tắc SO ngu ngốc với tối thiểu 6 ký tự để chỉnh sửa, nhưng thiếu '()' sau 'Trình xử lý mới', đó phải là 'Trình xử lý mới ()'
Jonathan Muller

2
Thay vì đặt mọi thứ vào luồng UI, bạn có thể làm: Handler mới (Looper.getMainLooper ())
Tobliug 18/03/2015

17

Tôi thích sử dụng View.postDelayed()phương pháp, mã đơn giản dưới đây:

mView.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do something after 1000 ms
    }
}, 1000);

1
Nó không tự đóng băng phần tử ui, bởi vì nó sẽ được lên lịch trên trình xử lý lượt xem?
JacksOnF1re

1
Không, tác vụ đã đăng sẽ được thực thi trong 1 giây, nhưng trong luồng UI thứ hai này thực hiện công việc hữu ích khác
demaksee

14

Đây là giải pháp ngắn nhất của tôi:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Do something after 100ms
    }
}, 100);

10
final Handler handler = new Handler(); 
Timer t = new Timer(); 
t.schedule(new TimerTask() { 
    public void run() { 
        handler.post(new Runnable() { 
            public void run() { 
                //DO SOME ACTIONS HERE , THIS ACTIONS WILL WILL EXECUTE AFTER 5 SECONDS...
            }
        }); 
    } 
}, 5000); 

10

Nếu bạn đang sử dụng Android Studio 3.0 trở lên, bạn có thể sử dụng biểu thức lambda. Phương thức callMyMethod()này được gọi sau 2 giây:

new Handler().postDelayed(() -> callMyMethod(), 2000);

Trong trường hợp bạn cần hủy bỏ việc chạy chậm, hãy sử dụng:

Handler handler = new Handler();
handler.postDelayed(() -> callMyMethod(), 2000);

// When you need to cancel all your posted runnables just use:
handler.removeCallbacksAndMessages(null);

Làm thế nào chúng ta có thể hủy bỏ điều này?
Damia Fuentes

Tôi ngạc nhiên khi có nhiều người ở đây sẽ vui vẻ di chuyển lên Kotlin, nhưng hoàn toàn bỏ qua Biểu thức Lambda là Java tiêu chuẩn.
TomDK

6

Tôi đề nghị Timer , nó cho phép bạn lên lịch một phương thức được gọi trong một khoảng thời gian rất cụ thể. Điều này sẽ không chặn UI của bạn và giữ cho ứng dụng của bạn được cộng hưởng trong khi phương thức đang được thực thi.

Tùy chọn khác, là Wait (); phương thức này sẽ chặn luồng hiện tại trong khoảng thời gian xác định. Điều này sẽ khiến UI của bạn ngừng đáp ứng nếu bạn thực hiện điều này trên luồng UI.


2
Thread.s ngủ () tốt hơn Object.wait (). Chờ đợi ngụ ý bạn sẽ được thông báo và đang đồng bộ hóa xung quanh một số hoạt động. Giấc ngủ cho thấy bạn chỉ đơn giản là không muốn làm gì trong một thời gian xác định. Hẹn giờ là cách để đi nếu bạn muốn hành động xảy ra không đồng bộ tại một số thời điểm sau đó.
Tim Bender

1
Điều đó đúng. Đó là lý do tại sao tôi liệt kê nó như một lựa chọn khác ;-)
Nate

6

Đối với một dòng đơn giản Xử lý trì hoãn bài, bạn có thể làm như sau:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        // Do someting
    }
}, 3000);

Tôi hi vọng cái này giúp được


5

Bạn có thể sử dụng điều này cho Giải pháp đơn giản nhất:

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //Write your code here
    }
}, 5000); //Timer is in ms here.

Khác, Dưới đây có thể là một giải pháp hữu ích sạch:

new Handler().postDelayed(() -> 
{/*Do something here*/}, 
5000); //time in ms

5

Bạn có thể làm cho nó sạch hơn nhiều bằng cách sử dụng các biểu thức lambda vừa được giới thiệu:

new Handler().postDelayed(() -> {/*your code here*/}, time);

5

Vì vậy, có một vài điều cần xem xét ở đây vì có rất nhiều cách để lột da con mèo này. Mặc dù câu trả lời đã được đưa ra và lựa chọn. Tôi nghĩ điều quan trọng là điều này phải được xem xét lại với các hướng dẫn mã hóa phù hợp để tránh bất kỳ ai đi sai hướng chỉ vì "câu trả lời đơn giản được chọn đa số".

Vì vậy, trước tiên hãy thảo luận về câu trả lời bị trì hoãn bài đơn giản là câu trả lời được lựa chọn chung cho chủ đề này.

Một vài điều cần xem xét. Sau khi trì hoãn bài đăng, bạn có thể gặp phải rò rỉ bộ nhớ, các vật thể chết, vòng đời đã biến mất và hơn thế nữa. Vì vậy, xử lý nó đúng cách cũng quan trọng. Bạn có thể làm điều này theo một vài cách.

Vì lợi ích của sự phát triển hiện đại, tôi sẽ cung cấp trong KOTLINE

Dưới đây là một ví dụ đơn giản về việc sử dụng chuỗi UI trên một cuộc gọi lại và xác nhận rằng hoạt động của bạn vẫn còn sống và tốt khi bạn nhấn vào cuộc gọi lại của mình.

  Handler(Looper.getMainLooper()).postDelayed({
            if(activity != null && activity?.isFinishing == false){
                txtNewInfo.visibility = View.GONE
            }
        }, NEW_INFO_SHOW_TIMEOUT_MS)

Tuy nhiên, điều này vẫn chưa hoàn hảo vì không có lý do gì để đánh lại cuộc gọi lại của bạn nếu hoạt động đã biến mất. Vì vậy, một cách tốt hơn sẽ là giữ một tham chiếu đến nó và loại bỏ các cuộc gọi lại như thế này.

    private fun showFacebookStylePlus1NewsFeedOnPushReceived(){
        A35Log.v(TAG, "showFacebookStylePlus1NewsFeedOnPushReceived")
        if(activity != null && activity?.isFinishing == false){
            txtNewInfo.visibility = View.VISIBLE
            mHandler.postDelayed({
                if(activity != null && activity?.isFinishing == false){
                    txtNewInfo.visibility = View.GONE
                }
            }, NEW_INFO_SHOW_TIMEOUT_MS)
        }
    }

và tất nhiên xử lý dọn dẹp trên onPause để nó không bị gọi lại.

    override fun onPause() {
        super.onPause()
        mHandler.removeCallbacks(null)
    }

Bây giờ chúng ta đã nói chuyện rõ ràng, hãy nói về một lựa chọn sạch hơn với coroutines và kotlin hiện đại :). Nếu bạn chưa sử dụng những thứ này, bạn thực sự đang bỏ lỡ.

   fun doActionAfterDelay() 
        launch(UI) {
            delay(MS_TO_DELAY)           
            actionToTake()
        }
    }

hoặc nếu bạn muốn luôn luôn khởi chạy UI trên phương thức đó, bạn chỉ cần làm:

  fun doActionAfterDelay() = launch(UI){ 
      delay(MS_TO_DELAY)           
      actionToTake()
  }

Tất nhiên, giống như PostDelayed, bạn phải đảm bảo rằng bạn xử lý việc hủy để bạn có thể thực hiện kiểm tra hoạt động sau cuộc gọi trì hoãn hoặc bạn có thể hủy nó trong onPause giống như tuyến khác.

var mDelayedJob: Job? = null
fun doActionAfterDelay() 
   mDelayedJob = launch(UI) {
            try {
               delay(MS_TO_DELAY)           
               actionToTake()
            }catch(ex: JobCancellationException){
                showFancyToast("Delayed Job canceled", true, FancyToast.ERROR, "Delayed Job canceled: ${ex.message}")
            }
        }
   }
}

// xử lý dọn dẹp

override fun onPause() {
   super.onPause()
   if(mDelayedJob != null && mDelayedJob!!.isActive) {
      A35Log.v(mClassTag, "canceling delayed job")
      mDelayedJob?.cancel() //this should throw CancelationException in coroutine, you can catch and handle appropriately
   }
}

Nếu bạn đặt khởi chạy (UI) vào chữ ký phương thức, công việc có thể được chỉ định trong dòng gọi mã.

Vì vậy, đạo đức của câu chuyện là an toàn với các hành động bị trì hoãn của bạn, đảm bảo bạn xóa các cuộc gọi lại hoặc hủy công việc của mình và tất nhiên xác nhận rằng bạn có vòng đời phù hợp để chạm vào các mục trong quá trình gọi lại chậm trễ của bạn. Các Coroutines cũng cung cấp các hành động hủy bỏ.

Cũng đáng lưu ý rằng bạn thường nên xử lý các ngoại lệ khác nhau có thể đi kèm với coroutines. Ví dụ: hủy bỏ, ngoại lệ, hết thời gian, bất cứ điều gì bạn quyết định sử dụng. Dưới đây là một ví dụ nâng cao hơn nếu bạn quyết định thực sự bắt đầu sử dụng coroutines.

   mLoadJob = launch(UI){
            try {
                //Applies timeout
                withTimeout(4000) {
                    //Moves to background thread
                    withContext(DefaultDispatcher) {
                        mDeviceModelList.addArrayList(SSDBHelper.getAllDevices())
                    }
                }

                //Continues after async with context above
                showFancyToast("Loading complete", true, FancyToast.SUCCESS)
            }catch(ex: JobCancellationException){
                showFancyToast("Save canceled", true, FancyToast.ERROR, "Save canceled: ${ex.message}")
            }catch (ex: TimeoutCancellationException) {
                showFancyToast("Timed out saving, please try again or press back", true, FancyToast.ERROR, "Timed out saving to database: ${ex.message}")
            }catch(ex: Exception){
                showFancyToast("Error saving to database, please try again or press back", true, FancyToast.ERROR, "Error saving to database: ${ex.message}")
            }
        }

1
Không có vấn đề gì với Rajiv, tôi sẽ tiến thêm một bước nữa và đề cập rằng sử dụng Live Data, các coroutine có thể nhận thức được vòng đời và tự hủy để tránh các cuộc gọi dọn dẹp, nhưng không muốn ném quá nhiều đường cong học tập vào một câu trả lời;)
Sam

3

Tôi tạo ra phương pháp đơn giản hơn để gọi này.

public static void CallWithDelay(long miliseconds, final Activity activity, final String methodName)
    {
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                try {
                    Method method =  activity.getClass().getMethod(methodName);
                    method.invoke(activity);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }, miliseconds);
    }

Để sử dụng nó, chỉ cần gọi: .CallWithDelay(5000, this, "DoSomething");


3
Phản ánh cho một nhiệm vụ cơ bản như vậy?
Tối đa

Vì câu hỏi để gọi phương thức tương tự như iOS performSelector. đây là cách tốt nhất để làm
HelmiB

3

Dưới đây một hoạt động khi bạn nhận được,

java.lang.R.78Exception: Không thể tạo trình xử lý bên trong luồng chưa được gọi là Looper.prepare ()

final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
  @Override
  public void run() {
    //Do something after 100ms
  }
}, 100);

3

Sử dụng Kotlin, chúng ta có thể đạt được bằng cách làm như sau

Handler().postDelayed({
    // do something after 1000ms 
}, 1000)

2

Nó rất dễ sử dụng CountDownTimer. Để biết thêm chi tiết https://developer.android.com/reference/android/os/CountDownTimer.html

import android.os.CountDownTimer;

// calls onTick every second, finishes after 3 seconds
new CountDownTimer(3000, 1000) { 

   public void onTick(long millisUntilFinished) {
      Log.d("log", millisUntilFinished / 1000);
   }

   public void onFinish() {
      // called after count down is finished
   } 
}.start();

2

Nếu bạn sử dụng RxAndroid thì xử lý luồng và xử lý lỗi trở nên dễ dàng hơn nhiều. Mã sau thực thi sau khi trì hoãn

   Observable.timer(delay, TimeUnit.SECONDS)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(aLong -> {
           // Execute code here
        }, Throwable::printStackTrace);

1

mọi người dường như quên làm sạch Handler trước khi đăng một tin nhắn hoặc tin nhắn mới trên đó. Mặt khác, họ có khả năng tích lũy và gây ra hành vi xấu.

handler.removeMessages(int what);
// Remove any pending posts of messages with code 'what' that are in the message queue.

handler.removeCallbacks(Runnable r)
// Remove any pending posts of Runnable r that are in the message queue.

1

Đây là một cách khó khăn khác: nó sẽ không ném ngoại lệ khi các thành phần UI thay đổi có thể chạy được.

public class SimpleDelayAnimation extends Animation implements Animation.AnimationListener {

    Runnable callBack;

    public SimpleDelayAnimation(Runnable runnable, int delayTimeMilli) {
        setDuration(delayTimeMilli);
        callBack = runnable;
        setAnimationListener(this);
    }

    @Override
    public void onAnimationStart(Animation animation) {

    }

    @Override
    public void onAnimationEnd(Animation animation) {
        callBack.run();
    }

    @Override
    public void onAnimationRepeat(Animation animation) {

    }
}

Bạn có thể gọi hoạt hình như thế này:

view.startAnimation(new SimpleDelayAnimation(delayRunnable, 500));

Hoạt hình có thể đính kèm vào bất kỳ xem.



1

Tôi thích những thứ sạch hơn: Đây là cách triển khai của tôi, mã nội tuyến để sử dụng bên trong phương thức của bạn

new Handler().postDelayed(new Runnable() {
  @Override
  public void run() {
    //Do something after 100ms
  }
}, 100);

0

Một giải pháp phù hợp trong Android:

private static long SLEEP_TIME = 2 // for 2 second
.
.
MyLauncher launcher = new MyLauncher();
            launcher.start();
.
.
private class MyLauncher extends Thread {
        @Override
        /**
         * Sleep for 2 seconds as you can also change SLEEP_TIME 2 to any. 
         */
        public void run() {
            try {
                // Sleeping
                Thread.sleep(SLEEP_TIME * 1000);
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
            //do something you want to do
           //And your code will be executed after 2 second
        }
    }

0

Giải pháp tương tự nhưng sạch hơn nhiều để sử dụng

Viết hàm này ra khỏi lớp

fun delay(duration: Long, `do`: () -> Unit) {

    Handler().postDelayed(`do`, duration)

}

Sử dụng:

delay(5000) {
    //Do your work here
}

Những gì `làm`?
Skizo-ozᴉʞS

Chỉ cần một cái tên, giữ bất cứ điều gì ở đó. dolà một phương thức sẵn có, vì vậy chúng ta phải sử dụng `để sử dụng nó làm tên biến
Manohar Reddy

Cảm ơn, nhưng tại sao lại sử dụng tên biến này? Ý tôi là chức năng của nó là gì.
Skizo-ozᴉʞS

1
Tôi đã nghĩ như thế dosau khi trì hoãn 3 giây
Manohar Reddy

0

Trong Android, chúng ta có thể viết mã kotlin bên dưới để thực hiện bất kỳ chức năng nào

class MainActivity : AppCompatActivity() {

private lateinit var handler: Handler

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    handler= Handler()
    handler.postDelayed({
        doSomething()
    },2000)
}

private fun doSomething() {
    Toast.makeText(this,"Hi! I am Toast Message",Toast.LENGTH_SHORT).show()
}
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.