나처럼 고생(?)하는 분들이 있을 것 같아서 아침이 밝아오는 새벽에 글을 남기고 새벽수영을 가려고 한다.
학교 수업시간에 prototype으로 App을 구현할 일이 있어서 뒤적거리던 중 C2DM을 사용해서 구현을 해야 하는 부분이 있었는데 ICS 4.0.4 로 Upgrade를 해서 문제가 생길 것 이라고는 상상도 못했다.
왜 안되지 올바른 code인데 하면서
이 code를 돌려보았다. 혹시나 하는 마음에 공기계로 갖고 있던 폰(GingerBread 2.3.4)에서는 잘 작동이 되었다.ㅎㄷㄷ
무슨 문제일까 하고 구글링을 하던 도중
여기에서 같은 문제를 발견했는데
'안드로이드 4.0 이후 버전부터 발생하는 오류로 추정되며, UI쓰레드(메인 쓰레드)에서 네트워크 통신을 사용하여 메인 쓰레드를 블록(Block)하게 될 경우 발생되는 오류라고 한다.'
해결책으로
'이 문제는 어떻게 해결해야하느냐구요?? 간단합니다. AsyncTask나 Thread를 사용하여 UI쓰레드에 영향을 주지 않도록 작성하면 됩니다. :) 조금 귀찮기는 하더라도, 네트워크 작업은 별도의 스레드에서 처리되도록 구현하는 것이 훨씬 좋으므로 이 기회에 AsyncTask를 사용하는 습관을 들이는 것도 나쁘지는 않을 듯 합니다. :)'
이렇게 해결하면 된다고 한다. 처음에는 무슨 말인지 긴가 민가 했었는데
예제 code의 부분을 살짝 수정해서 정상적으로 작동시킬 수 있었다.
= C2dmTest.java =
.
. 윗 부분 동일
.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//C2DM 등록ID 발급
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0)); // 어플리케이션ID
registrationIntent.putExtra("sender", "jack2yo@gmail.com"); //개발자ID
startService(registrationIntent); //서비스 시작(등록ID발급받기)
// 위에서 지정한 "app"와 "sender"은 맘대로 지정하시는게 아니라 구글에서 필요한 변수명들입니다.
msg_text = (EditText)findViewById(R.id.msg_text);
msg_send = (Button)findViewById(R.id.msg_send);
msg_send.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
try {
// 메시지를 보낼때 sender(발급받은 ID, 토큰인증값, 메시지)
sender(C2dm_BroadcastReceiver.registration_id,getAuthToken(),msg_text.getText().toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start(); // 스레드 실행
}
});
}
이 부분을 thread로 감싸주어서 실행을 시켜주니 Gingerbread 에서 처럼 정상적으로 C2DM 서비스가 동작을 했다.