Handler()가 폐지되면 무엇을 사용할 수 있습니까?
이 코드의 권장 해제 경고를 수정하려면 어떻게 해야 합니까?아니면 다른 방법이 있나요?
Handler().postDelayed({
context?.let {
//code
}
}, 3000)
가 없는 되지 않습니다.가 없는 컨스트럭터를 하는 것이 .이 시점에서는 다음 명령어를 지정하는 것이 좋습니다.Looper
스 in the를 Looper.getMainLooper()
★★★★★★ 。
Java에 사용
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
// Your Code
}
}, 3000);
코틀린에 사용
Handler(Looper.getMainLooper()).postDelayed({
// Your Code
}, 3000)
KotlinKotlin)의(null체크)를?
★★★★★★★★★★★★★★★★★」!!
을 사용하면 .Looper.getMainLooper()
Handler
UI 있습니다.
Handler(Looper.getMainLooper()).postDelayed({
Toast.makeText(this@MainActivity, "LOOPER", Toast.LENGTH_SHORT).show()
}, 3000)
" " 를 사용합니다.requireContext()
this@MainActivity
를 하고 있는 .
API 레벨 30부터는 2개의 컨스트럭터가 권장되지 않습니다.
구글은 그 이유를 다음과 같이 설명합니다.
핸들러 구축 중에 Looper를 암묵적으로 선택하면 조작이 사일런트하게 손실되거나(핸들러가 새로운 태스크와 종료가 예상되지 않는 경우), 크래시(Handler가 때때로 Looper 활성화되지 않은 스레드에 작성되는 경우), 또는 핸들러가 관련되어 있는 스레드가 저자가 예상한 것과 다른 레이스 조건이 발생할 수 있습니다.대신 실행자를 사용하거나 Looper #getMainLooper, {link android.view를 사용하여 Looper를 명시적으로 지정하십시오.View #getHandler} 또는 이와 유사합니다.호환성을 위해 암묵적인 스레드 로컬 동작이 필요한 경우, 새로운 핸들러(Looper.myLooper(), 콜백)를 사용하여 독자에게 명확하게 합니다.
해결책 1: 실행자 사용
1. 메인 스레드에서 코드를 실행합니다.
자바
// Create an executor that executes tasks in the main thread.
Executor mainExecutor = ContextCompat.getMainExecutor(this);
// Execute a task in the main thread
mainExecutor.execute(new Runnable() {
@Override
public void run() {
// You code logic goes here.
}
});
코틀린
// Create an executor that executes tasks in the main thread.
val mainExecutor = ContextCompat.getMainExecutor(this)
// Execute a task in the main thread
mainExecutor.execute {
// You code logic goes here.
}
2. 백그라운드 스레드에서 코드를 실행합니다.
자바
// Create an executor that executes tasks in a background thread.
ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();
// Execute a task in the background thread.
backgroundExecutor.execute(new Runnable() {
@Override
public void run() {
// Your code logic goes here.
}
});
// Execute a task in the background thread after 3 seconds.
backgroundExecutor.schedule(new Runnable() {
@Override
public void run() {
// Your code logic goes here
}
}, 3, TimeUnit.SECONDS);
코틀린
// Create an executor that executes tasks in a background thread.
val backgroundExecutor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
// Execute a task in the background thread.
backgroundExecutor.execute {
// Your code logic goes here.
}
// Execute a task in the background thread after 3 seconds.
backgroundExecutor.schedule({
// Your code logic goes here
}, 3, TimeUnit.SECONDS)
주의: 사용 후에는 실행 프로그램을 종료해야 합니다.
backgroundExecutor.shutdown(); // or backgroundExecutor.shutdownNow();
3. 백그라운드 스레드에서 코드를 실행하고 메인 스레드에서 UI를 업데이트합니다.
자바
// Create an executor that executes tasks in the main thread.
Executor mainExecutor = ContextCompat.getMainExecutor(this);
// Create an executor that executes tasks in a background thread.
ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();
// Execute a task in the background thread.
backgroundExecutor.execute(new Runnable() {
@Override
public void run() {
// Your code logic goes here.
// Update UI on the main thread
mainExecutor.execute(new Runnable() {
@Override
public void run() {
// You code logic goes here.
}
});
}
});
코틀린
// Create an executor that executes tasks in the main thread.
val mainExecutor: Executor = ContextCompat.getMainExecutor(this)
// Create an executor that executes tasks in a background thread.
val backgroundExecutor = Executors.newSingleThreadScheduledExecutor()
// Execute a task in the background thread.
backgroundExecutor.execute {
// Your code logic goes here.
// Update UI on the main thread
mainExecutor.execute {
// You code logic goes here.
}
}
해결책 2: 다음 중 하나의 생성자를 사용하여 Looper를 명시적으로 지정합니다.
1. 메인 스레드에서 코드를 실행합니다.
1.1 Looper가 있는 핸들러
자바
Handler mainHandler = new Handler(Looper.getMainLooper());
코틀린
val mainHandler = Handler(Looper.getMainLooper())
1.2 Looper와 핸들러가 있는 핸들러콜백
자바
Handler mainHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
return true;
}
});
코틀린
val mainHandler = Handler(Looper.getMainLooper(), Handler.Callback {
// Your code logic goes here.
true
})
2. 백그라운드 스레드에서 코드를 실행합니다.
2.1 Looper가 있는 핸들러
자바
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Create a handler to execute tasks in the background thread.
Handler backgroundHandler = new Handler(handlerThread.getLooper());
코틀린
// Create a background thread that has a Looper
val handlerThread = HandlerThread("HandlerThread")
handlerThread.start()
// Create a handler to execute tasks in the background thread.
val backgroundHandler = Handler(handlerThread.looper)
2.2. Looper와 Handler가 있는 핸들러.콜백
자바
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Create a handler to execute taks in the background thread.
Handler backgroundHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
return true;
}
});
코틀린
// Create a background thread that has a Looper
val handlerThread = HandlerThread("HandlerThread")
handlerThread.start()
// Create a handler to execute taks in the background thread.
val backgroundHandler = Handler(handlerThread.looper, Handler.Callback {
// Your code logic goes here.
true
})
참고: 사용 후에는 스레드를 해제해야 합니다.
handlerThread.quit(); // or handlerThread.quitSafely();
3. 백그라운드 스레드에서 코드를 실행하고 메인 스레드에서 UI를 업데이트합니다.
자바
// Create a handler to execute code in the main thread
Handler mainHandler = new Handler(Looper.getMainLooper());
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Create a handler to execute in the background thread
Handler backgroundHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
// Update UI on the main thread.
mainHandler.post(new Runnable() {
@Override
public void run() {
}
});
return true;
}
});
코틀린
// Create a handler to execute code in the main thread
val mainHandler = Handler(Looper.getMainLooper())
// Create a background thread that has a Looper
val handlerThread = HandlerThread("HandlerThread")
handlerThread.start()
// Create a handler to execute in the background thread
val backgroundHandler = Handler(handlerThread.looper, Handler.Callback {
// Your code logic goes here.
// Update UI on the main thread.
mainHandler.post {
}
true
})
권장되지 않는 함수는 핸들러의 컨스트럭터입니다.Handler(Looper.myLooper()) .postDelayed(runnable, delay)
대신에
코루틴 사용을 검토하다
scope.launch {
delay(3000L)
// do stuff
}
라이프 사이클 스코프를 사용하면, 이것은 보다 간단합니다.내부 액티비티 또는 fragment.
lifecycleScope.launch {
delay(2000)
// Do your stuff
}
또는 핸들러를 사용합니다.
Handler(Looper.myLooper()!!)
Handler()
★★★★★★★★★★★★★★★★★」Handler(Handler.Callback callback)
컨스트럭터는 권장되지 않습니다.버그나 크래쉬로 이어질 수 있기 때문입니다.실행자 Looper.
Java의 경우
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
//do your work here
}
}, 1000);
이것을 사용하다
Looper.myLooper()?.let {
Handler(it).postDelayed({
//Your Code
},2500)
}
실행자에 대한 자세한 내용은 핸들러 대신 실행자를 사용하십시오.
하려면 , 「」를 사용합니다.ScheduledExecutorService
:
ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
Runnable runnable = () -> {
public void run() {
// Do something
}
};
worker.schedule(runnable, 2000, TimeUnit.MILLISECONDS);
3가지 솔루션이 있습니다.
- 합니다: Looper는 Looper로 합니다.
Handler(Looper.getMainLooper()).postDelayed({ // code }, duration)
- 동작을 합니다.「 」 。
Handler(Looper.myLooper()!!).postDelayed({ // code }, duration)
- 를 사용합니다.
Thread
Thread({ try{ Thread.sleep(3000) } catch (e : Exception) { throw e } // code }).start()
핸들러 생성자에 looper 제공
Handler(Looper.getMainLooper())
[ Handler ]및 [Runnable]에 [Variable]를 사용하는 경우는, 다음과 같이 사용합니다.
private Handler handler;
private Runnable runnable;
handler = new Handler(Looper.getMainLooper());
handler.postDelayed(runnable = () -> {
// Do delayed stuff here
handler.postDelayed(runnable, 1000);
}, delay);
또한 onDestroy()에서 콜백을 삭제해야 합니다.
@Override
public void onDestroy() {
super.onDestroy();
if (handler != null) {
handler.removeCallbacks(runnable);
}
}
코루틴스 코틀린
private val SPLASH_SCREEN_TIME_OUT_CONST: Long = 3000
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
GlobalScope.launch {
delay(SPLASH_SCREEN_TIME_OUT_CONST)
goToIntro()
}
}
private fun goToIntro(){
startActivity(Intent(this, IntroActivity::class.java))
finish()
}
코틀린에 있는 이 구조물을 이용하는 것은 좋은 생각이다.
companion object Run {
fun after(delay: Long, process: () -> Unit) {
Handler(Looper.getMainLooper()).postDelayed({
process()
}, delay)
}
}
나중의 콜
Run.after(SPLASH_TIME_OUT) {
val action = SplashFragmentDirections.actionSplashFragmentToLogin()
v.findNavController().navigate(action)
}
import android.os.Looper
import android.os.Handler
inline fun delay(delay: Long, crossinline completion: () -> Unit) {
Handler(Looper.getMainLooper()).postDelayed({
completion()
}, delay)
}
예제:
delay(1000) {
view.refreshButton.visibility = View.GONE
}
Java 응답
쉽게 사용할 수 있는 방법을 썼습니다.이 메서드는 프로젝트에서 직접 사용할 수 있습니다.delayTimeMillis는 2000으로 할 수 있습니다.이것은 이 코드가 2초 후에 실행됨을 의미합니다.
private void runJobWithDelay(int delayTimeMillis){
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
//todo: you can call your method what you want.
}
}, delayTimeMillis);
}
문서(https://developer.android.com/reference/android/os/Handler#Handler()):
핸들러 구축 중에 Looper를 암묵적으로 선택하면 조작이 사일런트하게 손실되거나(핸들러가 새로운 태스크와 종료가 예상되지 않는 경우), 크래시(Handler가 때때로 Looper 활성화되지 않은 스레드에 작성되는 경우), 또는 핸들러가 관련되어 있는 스레드가 저자가 예상한 것과 다른 레이스 조건이 발생할 수 있습니다.대신 실행자를 사용하거나 Looper #getMainLooper, {link android.view를 사용하여 Looper를 명시적으로 지정하십시오.View #getHandler} 또는 이와 유사합니다.호환성을 위해 암묵적인 스레드 로컬 동작이 필요한 경우 새로운 핸들러(Looper.myLooper())를 사용하여 독자에게 명확하게 합니다.
Looper 없이 컨스트럭터 사용을 중지하고 대신 Looper를 지정해야 합니다.
예를 들어 풀스크린 액티비티가 처음부터 생성되었을 때 Android Studio 4.0.1에서 handler() 등의 코드가 생성됩니다.저도 Kotlin을 사용하도록 권유받고 있는 것은 알지만, 가끔 샘플 프로젝트를 사용하여 아이디어를 진행하기도 합니다.AS가 실제로 코드를 생성했을 때 AS로부터 질책을 받는 것은 이상하다고 생각합니다.오류를 검토하고 수정하는 것이 유용한 학술 활동일 수 있지만, AS가 우리 애호가들에게 새로운 클린 코드를 만들어 줄 수도 있습니다.
저는 이걸 주로 써요.
코드:
Handler(Looper.myLooper() ?: return).postDelayed({
// Code what do you want
}, 3000)
스크린샷:
언급URL : https://stackoverflow.com/questions/61023968/what-do-i-use-now-that-handler-is-deprecated
'programing' 카테고리의 다른 글
어레이를 인라인으로 선언할 방법이 있습니까? (0) | 2022.08.07 |
---|---|
C 메모리 관리 (0) | 2022.08.07 |
Route Leave 이전 Vue 라우터가 하위 구성 요소를 중지하지 않음 (0) | 2022.08.07 |
연결타임아웃 대 소켓타임아웃 (0) | 2022.08.07 |
wait()와 sleep()의 차이 (0) | 2022.08.07 |