Android 프로세스 간 및 스레드 간 통신 방법
프로세스: 특정 데이터 수집에 대한 특정 독립적인 기능을 가진 프로그램의 실행 활동입니다. 프로세스는 시스템의 리소스 할당 및 일정 관리를 위한 독립적인 단위입니다.
스레드(Thread): 프로세스의 개체이며 CPU 스케줄링 및 디스패치의 기본 단위로, 프로세스보다 작고 독립적으로 실행할 수 있는 기본 단위이다. 스레드 자체는 기본적으로 시스템 리소스를 소유하지 않고 작업에 필수적인 일부 리소스(예: 프로그램 카운터, 레지스터 집합 및 스택)만 소유하지만 프로세스가 가지고 있는 내용을 동일한 스레드에 속한 다른 스레드와 공유할 수 있습니다. 프로세스.
차이점:
(1) 프로그램에는 하나 이상의 프로세스가 있고 프로세스에는 하나 이상의 스레드가 있습니다.
(2) 분할 규모; 스레드는 프로세스보다 작기 때문에 멀티 스레드 프로그램의 동시성이 높습니다.
(3) 프로세스는 실행 중에 독립적인 메모리 단위를 갖는 반면, 여러 스레드는 메모리를 공유하지만 스레드 간에는 별도의 메모리 단위가 없습니다. 주소 공간, 하나의 스레드가 죽으면 전체 프로세스가 죽는 것을 의미합니다.
--------
1. 안드로이드 프로세스 간 통신 방식
1 .Bundle
Activity, Service, Receiver가 Intent를 통해 데이터를 전송하기 위해 Bundle을 운반할 수 있으므로, 하나의 프로세스에서 Intent를 통해 데이터를 운반하는 Bundle을 다른 프로세스의 컴포넌트로 보낼 수 있습니다.
단점: 번들에서 지원하지 않는 데이터 유형은 전송할 수 없습니다.
2.ContentProvider
ContentProvider는 Android의 4가지 주요 구성 요소 중 하나이며, 데이터를 테이블에 저장하고 이를 외부에 제공합니다. 프로세스 전반의 다른 애플리케이션에서. 사용법은 ContentProvider를 상속하고 onCreate, 쿼리, 업데이트, 삽입, 삭제 및 getType 메서드를 구현하는 것입니다. onCreate는 생성 중에 일부 초기화 작업을 수행하는 작업을 담당하며 데이터를 쿼리하고 수정합니다. . getType은 Uri 요청 유형을 나타내는 문자열을 반환합니다. 등록 후 ContentResolver를 사용하여 지정된 Uri를 요청할 수 있습니다.
3. 파일
두 프로세스는 동일한 파일에서 데이터를 교환할 수 있습니다. 텍스트 파일을 저장할 수 있을 뿐만 아니라 개체를 파일에 유지하고 다른 파일에서 복원할 수도 있습니다. 동시에 읽고 쓰는 경우 동시성 문제가 발생할 수 있다는 점에 유의해야 합니다.
4.브로드캐스트
브로드캐스트는 Android 시스템의 모든 애플리케이션에 브로드캐스트를 보낼 수 있으며, 크로스 프로세스 통신이 필요한 애플리케이션은 이러한 브로드캐스트를 들을 수 있습니다.
5.AIDL 메서드
서비스는 콘텐츠 제공자와 유사하며 다른 애플리케이션의 데이터에도 액세스할 수 있습니다. 콘텐츠 제공자는 커서 개체를 반환하는 반면 서비스는 Java 개체를 반환합니다. 프로세스 간에 통신할 수 있는 서비스를 AIDL 서비스라고 합니다.
?AIDL은 서버가 클라이언트에서 호출하도록 노출하는 인터페이스를 정의하는 반면 AIDL은 서버가 병렬로 처리할 수 있도록 하는 반면 메신저는 AIDL을 캡슐화한 후에만 직렬로 실행할 수 있으므로 메신저는 일반적으로 메시지로 사용됩니다. 옮기다.
6. 메신저
메신저는 AIDL을 기반으로 구현됩니다. 서버(수동측)는 클라이언트(활성측) 연결을 처리하기 위한 서비스를 제공하고 메신저를 생성하기 위한 핸들러를 유지합니다. onBind 중에 메신저의 바인더를 반환합니다.
양 당사자는 메신저를 사용하여 데이터를 보내고 핸들러를 사용하여 데이터를 처리합니다. 메신저는 데이터를 처리하기 위해 핸들러에 의존하므로 직렬입니다. 즉, 핸들러가 여러 메시지를 받으면 순서대로 대기하고 처리해야 합니다.
7. 소켓
소켓 방법은 네트워크를 통해 데이터를 교환하는 것입니다. 요청은 하위 스레드에서 이루어져야 합니다. 그렇지 않으면 메인 스레드가 차단됩니다. 클라이언트와 서버가 연결되면 지속적으로 데이터를 전송할 수 있으므로 실시간 데이터 전송에 더 적합합니다.
2. Android 스레드 간 통신 방법
일반적으로 말하면, 스레드 간 통신은 주로 호스트를 참조합니다. 스레드(UI 스레드라고도 함)와 하위 스레드 간 통신에는 두 가지 주요 방법이 있습니다.
1. AsyncTask 메커니즘
AsyncTask, 비동기 작업, 즉 UI 스레드에서 실행 시 백그라운드에서 일부 비동기 작업을 수행할 수 있습니다. AsyncTask는 UI 스레드를 쉽고 정확하게 사용할 수 있으며 명시적으로 사용하지 않고도 결과를 UI에 다시 제공할 수 있습니다. 작업자 스레드 또는 핸들러 메커니즘. 그러나 AsyncTask는 단기 작업(최대 몇 초 내에 종료되어야 하는 작업)에만 사용할 수 있습니다. 오랫동안 백그라운드에서 실행해야 하는 경우 AsyncTask는 적합하지 않으며 다른 API를 통해서만 구현할 수 있습니다. 자바에서 제공.
2. 핸들러 메커니즘
Object 클래스에서 상속된 핸들러는 핸들러가 생성될 때 메시지 객체 또는 실행 가능 객체를 보내고 처리하는 데 사용됩니다. 현재 스레드의 Looper 객체. (현재 스레드의 Looper가 비어 있거나 존재하지 않는 경우 예외가 발생합니다. 이때 Looper 객체를 생성하려면 스레드에서 Looper.prepare()를 적극적으로 호출해야 합니다. ). Handler를 사용하는 주요 기능은 후속 프로세스에서 Message 객체를 전송 및 처리하고 다른 스레드가 특정 작업(예: 작업 스레드의 Handler 객체를 통해 Message 객체를 전송하고 UI 스레드가 UI를 업데이트하도록 하는 등)을 완료하도록 하는 것입니다. 그런 다음 UI 스레드 MessageQueue에서 메시지 개체를 가져오고(메시지 개체 제거는 관련 Looper 개체에 의해 완료됨) 이에 따라 응답합니다.
3. 두 개의 Android 하위 스레드 간의 통신
인터뷰 과정에서 일부 면접관은 Android 하위 스레드 간의 통신 방법에 대해 질문할 수 있습니다. 왜냐하면 대부분의 프로그래머는 주로 초점을 맞추고 있기 때문입니다. Android 메인 스레드와 하위 스레드 간의 통신이므로 이 문제는 사람들을 쉽게 혼란스럽게 만들 수 있습니다.
메인 스레드와 하위 스레드 간의 통신은 메인 스레드의 핸들러를 사용하여 하위 스레드의 메시지를 메인 스레드의 루퍼로 보내거나 메인 스레드의 핸들러를 사용할 수 있습니다. 실행 가능을 통해 루퍼에 메시지를 보냅니다. 그런데 루퍼는 기본적으로 메인 스레드에 존재하고, 하위 스레드에는 루퍼가 없습니다. 어떻게 해야 할까요? 실제로 원리는 매우 간단합니다. 루퍼를 하위 스레드에 바인딩하고 핸들러를 만듭니다. 다른 스레드에서 이 핸들러를 통해 메시지를 보내면 하위 스레드 간의 통신이 이루어질 수 있습니다.
하위 스레드가 핸들러를 생성하는 두 가지 방법:
방법 1: 하위 스레드를 위한 Looper 객체 생성:
new Thread(new Runnable() {
p>public void run() {?
Looper.prepare();? // 이 스레드에 대한 Looper 객체를 생성합니다. Thead에는 단 하나의 Looper 객체가 있습니다. /p>
핸들러 핸들러 = new Handler(){?
@Override?
public void handlerMessage(Message msg) {?
토스트. makeText(getApplicationContext(), "handleMessage ", Toast.LENGTH_LONG).show();?
}?
};?
handler.sendEmptyMessage( 1);?
Looper.loop(); // MessageQueue에 메시지가 있는지 지속적으로 순회합니다.
};?
}).start( );
- -------
방법 2: 메인 스레드의 루퍼를 가져오거나 UI 스레드의 루퍼:
new Thread(new Runnable() {
public void run() {?
Handler handler = new Handler(Looper. getMainLooper()){ // 차이점은 다음과 같습니다!! ?
@Override?
public void handlerMessage(Message msg) {?
Toast.makeText (getApplicationContext(), "handleMessage", Toast.LENGTH_LONG ).show();?
}?
};?
handler.sendEmptyMessage(1 );?
}; ?
}).start();
---------------- --------