android 안드로이드 - AsyncTask에 여러 프리미티브 매개 변수를 전달하려면 어떻게해야합니까?




3 Answers

간단한 컨테이너에 프리미티브를 랩핑하고 AsyncTask에 매개 변수로 전달하면됩니다.

private static class MyTaskParams {
    int foo;
    long bar;
    double arple;

    MyTaskParams(int foo, long bar, double arple) {
        this.foo = foo;
        this.bar = bar;
        this.arple = arple;
    }
}

private class MyTask extends AsyncTask<MyTaskParams, Void, Void> {
    @Override
    protected void doInBackground(MyTaskParams... params) {
        int foo = params[0].foo;
        long bar = params[0].bar;
        double arple = params[0].arple;
        ...
    }
}

이것을 다음과 같이 부르십시오.

MyTaskParams params = new MyTaskParams(foo, bar, arple);
MyTask myTask = new MyTask();
myTask.execute(params);
동기 비동기

AsyncTask 클래스에 2 개의 매개 변수를 전달하는 방법 과 같은 관련 질문이 있습니다 . ,하지만 AsyncTask에 여러 프리미티브를 매개 변수로 전달하기가 힘들어서 내가 발견 한 것을 공유하려고합니다. 이 미묘함은 기존의 질문과 답변에 포착되지 않으므로 동일한 문제가 발생하여 고통을 덜어주는 사람을 돕고 싶습니다.

질문은 이것입니다 : 백그라운드에서 실행될 AsyncTask에 전달하려는 여러 프리미티브 매개 변수 (예 : 두 개의 long)가 있습니다. 어떻게 수행 할 수 있습니까? (내 답변은 ... 잠시 동안이 고생을 한 후에 발견 할 수 있습니다.)




AsyncTask에 여러 프리미티브를 전달하는 것은 (엄밀히 말하면) 불가능합니다. 예를 들어 myTask.execute(long1, long2) 를 수행하고 private class myTask extends AsyncTask<long, Void, Void> 를 설정하려는 경우 private class myTask extends AsyncTask<long, Void, Void> 는 해당 메서드로 private class myTask extends AsyncTask<long, Void, Void> 를 확장합니다.

@Override
protected LocationItemizedOverlay doInBackground(long... params) {...}

당신의 IDE는 아마도 슈퍼 타입 메소드를 오버라이드 할 필요가 있다고 불평 할 것입니다. doInBackground 에 대해 Varargs 메서드 서명을 사용하고 있습니다. 여기서 (long... params) 는 "params라는 배열에 저장되는 long 수의 변수를 허용합니다. 어떤 원인을 완전히 이해하지 못합니다. 컴파일러 / IDE 불만이 제기되어야하지만 제네릭 클래스 Params 가 정의 된 방식과 관련이 있다고 생각합니다.

어쨌든, 원시 타입을 원시가 아닌 래퍼 (예 : int => Integer, long => Long 등)로 올바르게 캐스트하면 아무런 문제없이 원하는 것을 얻을 수 있습니다. 사실, 프리미티브를 명시 적으로 비 프리미티브로 변환 할 필요가 없습니다. 자바가 당신을 위해 그것을 처리하는 것 같습니다. 다음과 같이 ASyncTask를 설정하면됩니다 (long의 경우).

private class MyTask extends AsyncTask<Long, Void, Void> {

    @Override
    protected void doInBackground(Long... params) {
        // Do stuff with params, for example:
        long myFirstParam = params[0]
    }
    ...
}

그런 다음 원래 의도대로이 클래스를 사용할 수 있습니다. 예 :

MyTask myTask = new MyTask();
myTask.execute(long1, long2);

또는 원하는 모든 수의 프리미티브에 대해 동일한 유형이어야 함을 지정하십시오. 여러 유형의 프리미티브를 전달해야하는 경우에도이 작업을 수행 할 수 있지만 위의 값을 다음과 같이 수정해야합니다.

private class MyTask extends AsyncTask<Object, Void, Void> {

    @Override
    protected void doInBackground(Object... params) {
        // Do stuff with params, for example:
        long myLongParam = (Long) params[0];
        int myIntParam = (Integer) params[1];

    }
    ...
}

이것은보다 유연하지만 매개 변수를 각각의 유형으로 명시 적으로 형변환해야합니다. 이 유연성이 필요하지 않으면 (즉 단일 데이터 유형), 약간 더 읽기 쉬워서 첫 번째 옵션을 계속 사용하는 것이 좋습니다.




내장 된 execute 메서드는 Params의 배열을 받아들이지 만 모두 정의 된 형식이어야합니다. 따라서 PARAM 형식을 OBJECT로 설정하면 개체의 자식 인 동안 원하는대로 전달할 수 있습니다. ...

private class MyTask extends AsyncTask<Object, Void, Void> {

그런 다음 doInBackGround에서 각 매개 변수를 필요한 순서대로 간단히 캐스팅합니다.

 @Override
 protected void doInBackground(Object... params) {
     Context t = (Context)parms[0];
     String a = (String) params[1];
     List<LatLng> list = (List<LatLng>)params[2];
     .
     .
     .

실행은 간단합니다.

 new MyTask().execute(context,somestring,list_of_points);

자신의 래퍼 클래스, 또는 번들, 해시 또는 무언가로 래핑하는 것만 큼 좋은 형식이 아닙니다. 명령은 양측에 따라 다르지만 작동합니다. 물론 배열을 HashMap (,)의 param으로 만들면 기본적으로 그 시점에서 번들을 구현하는 사용자 정의이지만 작동 할 것입니다.




Related

android android-asynctask primitive variadic-functions