'안드로이드 인터페이스'에 해당되는 글 2건

728x90

Interface 처리에 대한 사항을 정리차원에서 실 사용 예제에서 발췌하여 적어둔다.

3번 객체에 해당하는 부분은 여러 Class 에서 하나의 개발코드에 접근할 수 있도록 인터페이스 상속 처리를 했다.


1. 인터페이스 선언

public interface ISerialListener {
    void onReceive(int msg, int arg0, int arg1, String arg2, Object arg3);
}



2. SerialConnector 코드 발췌

public class SerialConnector {
    private Context mContext;
    private ISerialListener mListener; // 인터페이스 처리
    private Handler mHandler;
    private SerialMonitorThread mSerialThread;

    public SerialConnector(Context context, ISerialListener listener, Handler handler) {
        mContext = context;
        mListener = listener;
        mHandler = handler;
    }

    public void initialize() {
        List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(sUsbManager);
        if (availableDrivers.isEmpty()) {
            mListener.onReceive(Constants.MSG_SERIAL_ERROR, 0, 0, "Error: There is no available device. \n", null);
            return;
        }

        sDriver = availableDrivers.get(0);
        if(sDriver == null) {
            mListener.onReceive(Constants.MSG_SERIAL_ERROR, 0, 0, "Error: Driver is Null \n", null);
            return;
        }

        try {
            sPort.open(mConnection);
            if(BaudRate.isEmpty()){ // 통신 속도 설정값 가져와서 세팅
                sPort.setParameters(9600, 8, 1, 0);  // baudrate:9600, dataBits:8, stopBits:1, parity:N
            } else {
                sPort.setParameters(Integer.parseInt(BaudRate), Integer.parseInt(DataBit), Integer.parseInt(StopBit), Integer.parseInt(Parity));
            }
        } catch (IOException e) {
            mListener.onReceive(Constants.MSG_SERIAL_ERROR, 0, 0, "Error: Cannot open port \n" + e.toString() + "\n", null);
        } finally {
        }

        startThread();
    }

    public void finalize() {
        try {
            sDriver = null;
            stopThread();

            sPort.close();
            sPort = null;
        } catch(Exception ex) {
            mListener.onReceive(Constants.MSG_SERIAL_ERROR, 0, 0, "Error: Cannot finalize serial connector \n" + ex.toString() + "\n", null);
        }
    }

    /*****************************************************
     *    private methods
     ******************************************************/
    // start thread
    private void startThread() {
        mListener.onReceive(Constants.MSG_SERIAL_ERROR, 0, 0, "Start serial monitoring thread \n", null);
        if(mSerialThread == null) {
            mSerialThread = new SerialMonitorThread();
            mSerialThread.start();
        }
    }
    // stop thread
    private void stopThread() {
        if(mSerialThread != null && mSerialThread.isAlive())
            mSerialThread.interrupt();
        if(mSerialThread != null) {
            mSerialThread = null;
        }
    }

    /*****************************************************
     *    Sub classes, Handler, Listener
     ******************************************************/
    public class SerialMonitorThread extends Thread {
        @Override
        public void run() {
            byte readBuffer[] = new byte[4096];

            while(!Thread.interrupted()) {
                if(sPort != null) {
                    Arrays.fill(readBuffer, (byte)0x00);

                    try {
                        // Read and Display to Terminal
                        int numBytesRead = sPort.read(readBuffer, 1000);
                        if(numBytesRead > 0) {

                            // Print message length
                            Message msg = mHandler.obtainMessage(Constants.MSG_READ_DATA_COUNT, numBytesRead, 0, new String(readBuffer));
                            mHandler.sendMessage(msg);

                        } // End of if(numBytesRead > 0)
                    } catch (IOException e) {
                        Message msg = mHandler.obtainMessage(Constants.MSG_SERIAL_ERROR, 0, 0, "Error # run: " + e.toString() + "\n");
                        mHandler.sendMessage(msg);
                    }
                }

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }

            }    // End of while() loop
            finalizeThread();
        }    // End of run()
    }    // End of SerialMonitorThread

}


3. 객체 구현

핵심사항만 발췌하여 유사한 코드 구현시 활용 차원으로 적어둔다.

public class AAA extends AppCompatActivity {
    private static final String TAG = "AAA";
    Context mContext;

    private ActivityHandler mHandler = null;
    private SerialListener mSerialListener = null;
    private SerialConnector mSerialConnector = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tam_ss);
        mContext = AAA.this;
        initView();
    }

    private void initView() {
        connectUsb();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        connectUsb();
    }

    @Override
    protected void onDestroy() {
        releaseUsb();
        super.onDestroy();
    }

    private void connectUsb() {
        searchEndPoint();
        if (usbInterfaceFound != null) {
            setupUsbComm();
        }
    }

    private void releaseUsb() {
        textStatus.setText("releaseUsb()");
        mSerialConnector.finalize();
    }

    private boolean setupUsbComm() {
        boolean success = false;

        UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
        Boolean permitToRead = manager.hasPermission(deviceFound);

        if (permitToRead) {
            usbDeviceConnection = manager.openDevice(deviceFound);
            if (usbDeviceConnection != null) {
                // Initialize
                mSerialListener = new SerialListener();
                mHandler = new ActivityHandler();

                // Initialize Serial connector and starts Serial monitoring thread.
                mSerialConnector = new SerialConnector(mContext, mSerialListener, mHandler);
                mSerialConnector.initialize();
            }
        } else {
            manager.requestPermission(deviceFound, mPermissionIntent);
            textStatus.setText("Permission: " + permitToRead);
        }
        return success;
    }

    public class SerialListener implements ISerialListener {
        public void onReceive(int msg, int arg0, int arg1, String arg2, Object arg3) {
            switch(msg) {
                case Constants.MSG_DEVICD_INFO:
                    updateReceivedData(arg2);
                    break;
                case Constants.MSG_DEVICE_COUNT:
                    updateReceivedData(Integer.toString(arg0) + " device(s) found \n");
                    break;
                case Constants.MSG_READ_DATA_COUNT:
                    updateReceivedData(Integer.toString(arg0) + " buffer received \n");
                    break;
                case Constants.MSG_READ_DATA:
                    if(arg3 != null) {
                        updateReceivedData((String)arg3);
                    }
                    break;
                case Constants.MSG_SERIAL_ERROR:
                    updateReceivedData(arg2);
                    break;
                case Constants.MSG_FATAL_ERROR_FINISH_APP:
                    finish();
                    break;
            }
        }
    }

    public class ActivityHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case Constants.MSG_DEVICD_INFO:
                    updateReceivedData((String)msg.obj);
                    break;
                case Constants.MSG_DEVICE_COUNT:
                    updateReceivedData(Integer.toString(msg.arg1) + " device(s) found \n");
                    break;
                case Constants.MSG_READ_DATA_COUNT:
                    updateReceivedData(((String)msg.obj));
                    break;
                case Constants.MSG_READ_DATA:
                    if(msg.obj != null) {
                        updateReceivedData((String)msg.obj);
                    }
                    break;
                case Constants.MSG_INPUT_READ:
                    updateReceivedData((String)msg.obj);
                    mDumpTextView.setTextColor(Color.BLUE);
                    break;
                case Constants.MSG_SERIAL_ERROR:
                    updateReceivedData((String)msg.obj);
                    break;
            }
        }
    }
}


'안드로이드 > Interface' 카테고리의 다른 글

Java Interface 예제  (0) 2019.11.18
Android Interface AsyncTask 예제  (0) 2019.11.05
Java Interface Example  (0) 2019.09.05
Java 인터페이스(interface) 개요  (0) 2019.08.20
Android Interface 예제 ★★★  (0) 2018.08.22
블로그 이미지

Link2Me

,
728x90

안드로이드 인터페이스 처리하는 걸 많이 다뤄보지 않아서 그런지 인터페이스 사용을 자유롭게 하지 못한다.


"이것이 자바다" 를 유투브에서 인터페이스 강좌를 찾아서 들어보면 설명을 참 잘 해준다.

https://www.youtube.com/watch?v=8GcOYOd67KY


구글 검색으로 블로그에 적혀 있는 내용만으로 손쉽게 인터페이스 처리 코드를 만들줄 알면 고민되지 않겠지만 대게는 단순한 구현 예시만 나와 아직 초보를 탈출하지 못한 나에겐 어렵다.


로그인한 세션 정보를 받아서 다음 단계를 처리해야 하는 어플을 테스트하다보니 인터페이스 부분이 너무 약해서 막힌다.


가장 먼저 인터페이스를 정의한다.

OnCallbackListener.java

public interface OnCallbackListener<T> {
    void onSuccess(T object);
    void onFailure(Exception e);
}
 


두번째 단계는 위 그림에서 개발코드에 해당되는 SessionProcessTask.java 파일을 구현한다.

import android.content.Context;
import android.os.AsyncTask;

public class SessionProcessTask extends AsyncTask<Void, Void, String> {
    private Context mContext;
    private OnCallbackListener<String> mCallBack;
    public Exception mException;


    // 변수를 먼저 선언하고 ALT+ Insert 키를 생성자 생성시 아래와 같은 순서로 생성자 자동 생성 가능

    public SessionProcessTask(Context mContext, OnCallbackListener<String> mCallBack) {
        this.mContext = mContext;
        this.mCallBack = mCallBack;
    }

    @Override
    protected String doInBackground(Void... params) {

        try {
            // 백그라운드 작업할 코드를 여기에서 구현한다.
            return "Welcome to my blog.";

        } catch (Exception e) {
            mException = e;
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        if (mCallBack != null) {
            if (mException == null) {
                mCallBack.onSuccess(result);
            } else {
                mCallBack.onFailure(mException);
            }
        }
    }
}


객체를 구현할 MainActivity.java 파일의 구현 내용이다.

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = MainActivity.this;

        // 객체 생성
        SessionProcessTask processTask = new SessionProcessTask(mContext, new OnCallbackListener<String>() {
            @Override
            public void onSuccess(String object) {
                Toast.makeText(mContext, "SUCCESS: "+object, Toast.LENGTH_LONG).show();
                ActionActivity android = new ActionActivity(mContext);
                android.btnTouch();
            }

            @Override
            public void onFailure(Exception e) {
                Toast.makeText(mContext, "ERROR: " + e.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
        processTask.execute();
    }

}


onSuccess 결과를 받으면 후속으로 

ActionActivity android = new ActionActivity(mContext);

android.btnTouch();

를 실행하도록 했다.


이제 이와 관련된 코드를 또다른 인터페이스를 통해 처리되도록 구현했다.

// OnLoadListener.java 파일

public interface OnLoadListener { 
    public void onLoadFinish();
}

// ImageLoader.java 파일

import android.content.Context;
import android.widget.Toast;

public class ImageLoader {
    private Context mContext;
    private OnLoadListener loadListener;

    public ImageLoader(Context context, OnLoadListener loadListener) {
        mContext = context;
        this.loadListener = loadListener;
    }

    public void start(){
        try {
            System.out.println("이미지를 로딩합니다.");
            Toast.makeText(mContext, "이미지를 로딩합니다.", Toast.LENGTH_LONG).show();
            Thread.sleep(1000);
            loadListener.onLoadFinish();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

// ActionActivity.java 파일

import android.content.Context;
import android.widget.Toast;

public class ActionActivity implements OnLoadListener {
    private Context mContext;

    public ActionActivity(Context mContext) {
        this.mContext = mContext;
    }

    public void btnTouch(){
        ImageLoader imageLoader = new ImageLoader(mContext,this);
        imageLoader.start();
    }

    @Override
    public void onLoadFinish() {
        Toast.makeText(mContext, "토스트 팝업을 띄웁니다.", Toast.LENGTH_LONG).show();
        System.out.println("토스트 팝업을 띄웁니다.");
    }
}


Log 메시지를 통해서 확인할 수도 있지만, Toast 메시지 창을 띄워서 순차적으로 실행되는 결과를 확인할 수 있게 했다.

아직 응용력이 떨어지는 나를 위해 테스트하고 적어둔다.

구글링하다가 발견한 좋은 글이 와 닿는다.

인터넷에서 짜집기한 것만 읽지 말고, 책을 읽어라. 같은 책을 여러 번 읽어라. 꾸준히 해라.

하지만, 요즈음에는 "유투브 강좌를 열심히 봐라" 라고 하는게 더 맞을 거 같다.

좋은 강좌들이 너무 많이 오픈되어 있다.


테스트에 사용한 코드

Interface_src.zip


'안드로이드 > Interface' 카테고리의 다른 글

Android 인터페이스 상속 ISerialListener 예제  (0) 2019.12.12
Java Interface 예제  (0) 2019.11.18
Java Interface Example  (0) 2019.09.05
Java 인터페이스(interface) 개요  (0) 2019.08.20
Android Interface 예제 ★★★  (0) 2018.08.22
블로그 이미지

Link2Me

,