예 콜백 개념은 Java에도 매우 많이 존재합니다. 자바에서는이 같은 콜백을 정의
public interface TaskListener {
public void onFinished(String result);
}
하나는 종종 중첩이 같은 AsyncTask
내부 리스너 정의의 이러한 종류의 것입니다 :
public class ExampleTask extends AsyncTask<Void, Void, String> {
public interface TaskListener {
public void onFinished(String result);
}
...
}
그리고 AsyncTask
의 콜백의 완전한 구현이 보일 것이다 이와 같이 :
public class ExampleTask extends AsyncTask<Void, Void, String> {
public interface TaskListener {
public void onFinished(String result);
}
// This is the reference to the associated listener
private final TaskListener taskListener;
public ExampleTask(TaskListener listener) {
// The listener reference is passed in through the constructor
this.taskListener = listener;
}
@Override
protected String doInBackground(Void... params) {
return doSomething();
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// In onPostExecute we check if the listener is valid
if(this.taskListener != null) {
// And if it is we call the callback function on it.
this.taskListener.onFinished(result);
}
}
}
백그라운드 작업이 완료되면 바로 호출됩니다.
ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
@Override
public void onFinished(String result) {
// Do Something after the task has finished
}
});
task.execute();
아니면 같이 완전히 별도로 TaskListener
을 정의 할 수 있습니다 : 당신은이 같은 모든 일을 사용할 수 있습니다
ExampleTask.TaskListener listener = new ExampleTask.TaskListener() {
@Override
public void onFinished(String result) {
// Do Something after the task has finished
}
};
ExampleTask task = new ExampleTask(listener);
task.execute();
또는이 같은 TaskListener
하위 클래스 :
public class ExampleTaskListener implements TaskListener {
@Override
public void onFinished(String result) {
}
}
을 그리고 다음과 같이 사용하십시오 :
ExampleTask task = new ExampleTask(new ExampleTaskListener());
task.execute();
당신은 물론 단지 AsyncTask
의 onPostExecute()
메소드를 오버라이드 (override) 할 수 있지만, 실제로는 아주 나쁜 관행을 권장하고 대부분의 경우되지 않습니다. 예를 들어, 당신은이 작업을 수행 할 수 있습니다 :
ExampleTask task = new ExampleTask() {
@Override
public void onPostExecute(String result) {
super.onPostExecute(result);
// Your code goes here
}
};
이 별도의 리스너 인터페이스 위의 구현으로 단지뿐만 아니라 작동하지만이에 몇 가지 문제가 있습니다 :
우선 무엇보다도 당신은 실제로 끊을 수있다 ExampleTask
모두 함께 위의 호출은 모두 super.onPostExecute()
입니다. 개발자가 위와 같이 onPostExecute()
을 덮어 쓰고 수퍼 전화를 포함시키지 않았거나 어떤 이유에서든 간단하게 삭제하는 것을 잊어 버린 경우 ExampleTask
의 메소드는 더 이상 호출되지 않습니다. 예를 들어 TaskListener
의 전체 리스너 구현은 콜백 호출이 onPostExecute()
에 구현 된 이후 갑자기 더 이상 작동하지 않습니다. TaskListener
을 무의식적으로 또는 무의식적으로 ExampleTask
의 상태에 영향을 주어 여러 가지 다른 방법으로 깨뜨릴 수 있으므로 더 이상 작동하지 않습니다.
실제로 이와 같은 방법을 재정의 할 때 일어나는 일을 살펴보면 어떤 일이 벌어지고 있는지 훨씬 명확하게 알 수 있습니다.onPostExecute()
을 재정 의하여 ExampleTask
의 새 하위 클래스를 만듭니다.
public class AnotherExampleTask extends ExampleTask {
@Override
public void onPostExecute(String result) {
super.onPostExecute(result);
// Your code goes here
}
}
이 모든 것은 익명 클래스라는 언어 기능 뒤에 숨겨져 있습니다. 갑자기이 방법을 재정의하는 것은 더 이상 깨끗하지 않고 빠른 것으로 보이지 않습니다.
은 요약하면 :
- 이 같은 방법은 실제로 새로운 서브 클래스를 생성 재정의. 당신은 단지 콜백을 추가하는 것이 아니라,이 클래스가 어떻게 작동 하는지를 수정하고 있고, 무의식적으로 많은 것을 깨뜨릴 수 있습니다.
- 이와 같은 디버깅 오류는 a2의 단순한 고통 이상의 것일 수 있습니다. 갑자기
ExampleTask
이 Exceptions
을 던지거나 분명한 이유 때문에 더 이상 작동하지 않을 수 있기 때문에 실제로 코드를 수정하지 않았기 때문입니다.
- 각 클래스는 적절하고 의도 된 위치에 리스너 구현을 제공해야합니다. 물론
onPostExecute()
을 무시하여 나중에 추가 할 수는 있지만 항상 위험합니다. 그의 13k 평판을 가진 @flup조차도 자신의 대답에 super.onPostExecute()
전화를 포함하는 것을 잊어 버렸습니다. 숙련 된 개발자가 아닌 다른 사람들이 상상해보십시오!
- 작은 추상화는 결코 누구에게도 해를 끼치 지 않습니다. 특정 수신기를 작성하는 것은 약간 더 많은 코드 일 수 있지만 훨씬 좋은 해결책입니다. 코드는보다 깨끗하고 읽기 쉽고 유지 보수가 용이합니다.
onPostExecute()
을 덮어 쓰는 것처럼 단축키를 사용하면 약간의 편의를 위해 코드 품질이 희생됩니다. 장기적으로는 문제를 일으키는 좋은 아이디어는 결코 아닙니다.
어떻게 그런지 모르겠군요^_ ^. 비동기 작업을 사용하여 백그라운드 스레드를 만들고 코드 인 aka httprequest가 doInBackground() 메소드에 들어가고 이에 대한 returntype을 정의합니다. 백그라운드 작업이 완료되면 onPostExecute()가 호출되어 응답을 처리 할 코드를 작성하고 이제보기 및 모두를 업데이트합니다. 정의 된 진행 상황에 도달하면 트리거되는 progressupdate 메소드가 있습니다. 잠시 후에 설명서 링크를 얻을 수 있습니다. – Rico
http://developer.android.com/reference/android/os/AsyncTask.html – Rico