android studio ver. 3.1.4
kotlin_version = 1.2.61



기존 자바 프로젝트를 kotlin 으로 변경하던 중에 새로운 문제에 부딪히게 되었습니다.


Java로 작성된 Network 모듈 코드입니다.

public class NetworkManager {

    private NetworkManager(@NonNull Context c) {
    }

    public interface OnNetworkListener<T> {
        void OnNetworkResult(String requestId, T res);
    }

    public void request(OnNetworkListener listener) {
        ResponseBase res = new ResponseBase(0, "Test!!! ");
        if (listener != null) {
            listener.OnNetworkResult("", res);
        }
    }
}


public class ResponseBase {
    
    public static final int RETURN_CODE_SUCCESS = 0;    // 성공

    public int code = 0;
    public String message = "";

    public ResponseBase(int code, String msg) {
        code = code;
        message = msg;
    }

    public boolean isSuccess() {
        return code == RETURN_CODE_SUCCESS;
    }
}

Java에서 사용시 

NetworkManager.getInstance(getBaseContext()).request(new NetworkManager.OnNetworkListener<ResponseBase>() {
            @Override
            public void OnNetworkResult(String requestId, ResponseBase res) {
                Logger.d("res , ", res.isSuccess());
                Logger.d("res , ", res.message);
            }
        });

Kotlin에서 변형시

NetworkManager.getInstance(baseContext).request {
            requestId, res ->

        }

여기까지는 문제 없이 되었지만,
값을 사용하려고 보니 아래 그림과 같이 에러가 발생을 합니다. res를 인식하지 못해서 그런거라 판단이 됩니다.
그래서 캐스팅을 어떻게 해야하나 구글링을 시작했습니다.




그래도 딱히 시원한 답을 얻지 못해서 문서를 정독해보았습니다.

https://kotlinlang.org/docs/reference/typecasts.html



최종 코드는 아래와 같이 사용하였고,
저같은 경우는 res 가 여러 케이스로 들어올수 있으므로,
2번째처럼 명시적인 사용은 오류를 일으킬 가능성이 큽니다.

override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)

	NetworkManager.getInstance(baseContext).request {
		requestId, res ->
			if(res is ResponseBase) {   // java:: res instanceof ResponseBase
				d("res , ", res.isSuccess)
				d("res , ", res.message)
			}

			i("res 2 , ", (res as ResponseBase).isSuccess)  // java:: ((ResponseBase) res).isSuccess()
			i("res 2 , ", res.message)
	}
}


어느날 갑자기 styles.xml 파일의 Theme 부분에서
Cannot resolve symbol 'Theme' 라고 빨간색으로 나오는 이슈가 있었습니다.

이렇게 나오더라도, 빌드도 잘되며 Declaration 잘됩니다.

프로젝트에 아무 영향이 없지만,


찝찝한 마음을 떨쳐버릴수가 없어요. 난 이것을 없애 버려야겠다고 생각했습니다.



우선 구글링을 통해 3가지 공통적인 답을 얻을 수 있었습니다.


1.  menu > File > Sync Prjcet with Gradle files


2. menu > File > Invalidate Caches / Restart ....


3. .idea 폴더 / libraries 폴더 / Gradle__com_android_support_XXXXX.xml 파일 모두 지우기 




저와 같은 경우는 1,2 번은 별다른 효과를 얻지 못했습니다.


3번의 사항에서 파일들을 모두 제거하고,


Sync Prjcet with Gradle files을 실행하고 나니, 


아래와 같이 빨간색으로 된 Cannot resolve symbol 메시지들이 사라진 것을 확인 할 수 있었습니다~~

속이 후련하네요~









android studio ver. 3.1.4
kotlin_version = 1.2.60



AlertDialog 예제입니다.

먼저 Java 간단한 다이얼로그 예제를 작성하였습니다.


 

public class SplashActivity_j extends AppCompatActivity implements  View.OnClickListener {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);

        FrameLayout lay = findViewById(R.id.lay_push);
        lay.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.lay_push:
                AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(SplashActivity_j.this, R.style.Theme_AppCompat_Light_Dialog_Alert));
                builder.setTitle("제목");
                builder.setMessage("메시지 내용");
                builder.setPositiveButton("확인",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int id) {
                            }
                        });

                builder.setNegativeButton("취소",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int id) {
                            }
                        });
                builder.show();
                break;
        }
    }
}

아래는 코틀린으로 변환된 코드입니다.
{ dialog , id 는
{ _ , _ 이렇게 사용도 가능합니다.

class SplashActivity : AppCompatActivity(), View.OnClickListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

        // lay 클릭시
        val lay:FrameLayout = findViewById(R.id.lay_push)
        lay.setOnClickListener(this)
    }

    override fun onClick(v: View) {
        when(v.id) {
            R.id.lay_push -> {
                // 다이얼로그
                val builder = AlertDialog.Builder(ContextThemeWrapper(this@SplashActivity, R.style.Theme_AppCompat_Light_Dialog))
                builder.setTitle("제목(kotlin)")
                builder.setMessage("내용(Kotlin)")

                /*builder.setPositiveButton("확인") {dialog, id ->
                }
                builder.setNegativeButton("취소") {dialog, id ->
                }*/
                builder.setPositiveButton("확인") { _, _ ->
                    d("alert ok")
                }
                builder.setNegativeButton("취소") { _, _ ->
                    d("alert cancel")
                }

                builder.show()
            }
        }
    }
}


+ Recent posts