마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Activity 업데이트 관련입니다.

0 추천
안녕하세요.

 

서비스에서 LocalBroadCastManager의 sendBroadcast를 사용하여 Activity의 브로드캐스트 리시브를 통하여

 

메인 Activity의 TextView를 업데이트 하고싶습니다.

 

만약 서비스의 Run()안에서 1000번의 sendBroadcast를 액티비티로 보낼때

 

1000번의 루프를 돈 이후에 액티비티의 브로드캐스트(onReceive)가 동작합니다.

 

sendBroadcastSync 를 쓴다면, 액티비티의 브로드캐스트(onReceive)와 싱크를 이뤄지면서 TextView를 쓰는것으로 보이는데요. 결국 TextView는 루프가 끝난 다음에 한꺼번에 뿌리고 있네요.

 

당연히 액티비티의 브로드캐스트 OnReceive안에는 runOnUiThread로 UI 쓰레드 생성하여 쓰고 있습니다.

 

실시간으로 서비스가 루프를 돌면서 TextView를 갱신하고 싶은데. 루프중에는 UI 갱신이 안되네요.

 

감사합니다.
하우레스 (140 포인트) 님이 2014년 4월 15일 질문

1개의 답변

+1 추천
직접 코드를 보지 못해서 정확한 원인은 모르겠으나,

아마도 루프돌면서 브로드캐스트 보내는 부분의 코드를 잘못 작성하신듯 보이네요
Gradler (109,780 포인트) 님이 2014년 4월 16일 답변
public static LocalBroadcastManager broadcaster;

public static void sendResult(String message) {
    Intent intent = new Intent(COPY_RESULT);
    if(message != null)
        intent.putExtra(COPY_RESULT, message);
    broadcaster.sendBroadcastSync(intent);
}

위와 같이 보내고 있습니다.

sendBroadcast 로 할시에는 모든 루프가  끝나고 나서 Acrtivity에서 OnReceive하여 처리되고, sendBroadcastSync로 할시 루프중간중간 Activity의 OnReceive에 있는 runOnUiThread가 처리 되고 있네요.

원인을 아직 잘 모르겠습니다.
sendResult는 실제로 브로드캐스트를 보내는 부분이고, sendResult를 호출하는 부분 소스도 올려주셔야 할듯 합니다.
호출부분은 Service 에 있는 run에서

아래와 같이 하였을때

for(int j = 0; j < 100; j++)
{
    sendResult("???");
}

위와 같이 100번이건 1000번이건 돌리게 해도 실시간으로 Activity의 TextView가 추가되면서 돌아가지 않네요. 저 루프가 끝나고, Service의 run이 다 돌아야 Activity의 TextView가 갱신이 됩니다.
우선은 질문을 혼자만 알고 계신 내용을 기반으로 하시면 안되구요 아무나 봐도 이해하기 쉽게 하셔야 합니다..  Service의 run이라는 메소드는 따로 오버라이드 되는게 없으니 Runnable이나 Thread를 Service에서 따로 만들었고, 그 안에서 저 반복문 처리를 하고 있다는 말씀이신듯 한데 맞나요?
서비스는 implements Runnable 하여 run()메소드를 오버라이드 하여 쓰고 있습니다.

그 안에서는 위와 같이 처리하였습니다.
정확히 어떻게 구현했다는지 잘 이해가 안가는군요 그냥 처음부터 소스를 다 올려 두셨다면 답변하시는 분들도 이해가 쉽게 되었을 텐데..
어찌되었건 하시려는 내용을 구현해봤는데 잘 됩니다.
저는 Runnable이 아닌 Handler로 했습니다.


public class TestService extends Service {

    private int i = 0;
   
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
   
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        Log.e("TAG", "service onStartCommand()");
        i = intent.getIntExtra("count", 0);
        mHandler.sendEmptyMessageDelayed(0, 100);
        return super.onStartCommand(intent, flags, startId);
    }
       
    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            if (i < 100) {
                if (TestService.broadcaster != null) {
                    TestService.sendResult("" + i);
                }
                i++;
                mHandler.sendEmptyMessageDelayed(0, 100);
            }
        }
    };
   
    public static LocalBroadcastManager broadcaster;

    public static void sendResult(String message) {
        Intent intent = new Intent(TestActivity.FILTER_ACTION);
        intent.putExtra(TestActivity.FILTER_ACTION, message);
        broadcaster.sendBroadcastSync(intent);
    }

    public static void initBroadcaster(Context context) {
        Log.e("TAG", "initbroadcaster");
        broadcaster = LocalBroadcastManager.getInstance(context);
    }
}

public class TestActivity extends Activity {
   
    private MyReceiver mReceiver = new MyReceiver();
    private TextView textView;
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        textView = new TextView(this);
        setContentView(textView);
        Intent intent = new Intent(this, TestService.class);
        intent.putExtra("count", 0);
        startService(intent);
    }
   
    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter filter = new IntentFilter();
        filter.addAction(FILTER_ACTION);
        if (TestService.broadcaster == null) {
            TestService.initBroadcaster(getApplicationContext());
        }
        TestService.broadcaster.registerReceiver(mReceiver, filter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (TestService.broadcaster != null) {
            TestService.broadcaster.unregisterReceiver(mReceiver);
        }
    }

    private class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context arg0, Intent arg1) {
            final String extra = arg1.getStringExtra(FILTER_ACTION);
            Log.i(TAG, "onReceive : " + extra);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (textView != null) {
                        textView.setText(extra);
                    }
                }
            });
        }
    }
}
질문자님이 작성하신 소스가 왜 안되는지는 소스를 직접 봐야 알겠지만 대강 유추하기로는 Thread가 block 된 상태로 있다가 작업이 다 끝나면 한번에 UI 쪽에서 받아서 처리되는 문제인듯 싶네요
감사합니다 좋은 참조하겠습니다.~
...