ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 인턴근무 동안의 삽질 모음 (1)
    Memo 2021. 7. 17. 22:37

    회사에서의 안드로이드 개발 과정에서 사용할 데이터가 변경되곤 했다. 그 과정에서의 삽질이 좀 있었다.

     

    그 과정을 보면

     

    • 검색기능 - 데이터 변경 및 SQL을 구현하기 위한 눈물겨운 노력

     

    [공공데이터 포털-json 형식의 데이터]를 리사이클러 뷰를 통해 나타내려 했는데

    데이터가 쓸모없는 것들이라 이것을 회사가 가진 엑셀 (정적)데이터 기반으로 불러와서 쓰도록 바뀌었다.

    엑셀데이터는 총 13개 정도의 시트에 총 45000여 행, 13개의 애트리뷰트를 가졌다.

    지난학기에 데이터베이스 배운것도 있고 해서 처음엔 이걸 sql로 나타내려 했다.

    안드로이드 스튜디오에서는 SQLite를 지원한다.

     

    그러기 위해 엑셀(xlsx) → csv → sql 로 변환하는데 성공했다.

     

    sql로 변환하는 툴을 찾는데 거의 모든 시간을 쓴거 같다.

    이제 안드로이드 스튜디오에서 이걸 사용하기만 하면 된다. 근데 어떻게?

     

    https://hashcode.co.kr/questions/621/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98%EC%97%90%EC%84%9C-%EC%A1%B4%EC%9E%AC%ED%95%98%EB%8A%94-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95%EC%9D%B4-%EB%AD%94%EA%B0%95

     

    안드로이드 애플리케이션에서 존재하는 데이터베이스를 사용하는 방법이 뭔강?

    제가 이미 SQLite로 데이터베이스를 만들었는데요. 이 데이터베이스파일을 제 안드로이드 프로젝트에서 쓰고 싶어요. 새로 데이터베이스를 만드는거 말고 기존의 데이터베이스에 어떻게 접근할

    hashcode.co.kr

     

    책이랑 이글을 참조했던거 같다. 아마 같은 내용일것이다.

     

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;

    import android.content.Context;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.util.Log;

    public class DataBaseHelper extends SQLiteOpenHelper {
    private static String TAG = "DataBaseHelper"; //Logcat에 출력할 태그이름
    //디바이스 장치에서 데이터베이스의 경로
    private static String DB_PATH = "";
    private static String DB_NAME = "YourDbName"; // 데이터베이스 이름
    private SQLiteDatabase mDataBase;
    private final Context mContext;

    public DataBaseHelper(Context context) {
    super(context, DB_NAME, null, 1);// 1은 데이터베이스 버젼
    if (android.os.Build.VERSION.SDK_INT >= 17) {
    DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
    } else {
    DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
    }
    this.mContext = context;
    }

    public void createDataBase() throws IOException {
    //데이터베이스가 없으면 asset폴더에서 복사해온다.

    boolean mDataBaseExist = checkDataBase();
    if (!mDataBaseExist) {
    this.getReadableDatabase();
    this.close();
    try {
    //Copy the database from assests
    copyDataBase();
    Log.e(TAG, "createDatabase database created");
    } catch (IOException mIOException) {
    throw new Error("ErrorCopyingDataBase");
    }
    }
    }

    ///data/data/your package/databases/Da Name <-이 경로에서 데이터베이스가 존재하는지 확인한다
    private boolean checkDataBase() {
    File dbFile = new File(DB_PATH + DB_NAME);
    //Log.v("dbFile", dbFile + " "+ dbFile.exists());
    return dbFile.exists();
    }

    //assets폴더에서 데이터베이스를 복사한다.
    private void copyDataBase() throws IOException {
    InputStream mInput = mContext.getAssets().open(DB_NAME);
    String outFileName = DB_PATH + DB_NAME;
    OutputStream mOutput = new FileOutputStream(outFileName);
    byte[] mBuffer = new byte[1024];
    int mLength;
    while ((mLength = mInput.read(mBuffer)) > 0) {
    mOutput.write(mBuffer, 0, mLength);
    }
    mOutput.flush();
    mOutput.close();
    mInput.close();
    }

    //데이터베이스를 열어서 쿼리를 쓸수있게만든다.
    public boolean openDataBase() throws SQLException {
    String mPath = DB_PATH + DB_NAME;
    //Log.v("mPath", mPath);
    mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
    //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
    return mDataBase != null;
    }

    @Override
    public synchronized void close() {
    if (mDataBase != null)
    mDataBase.close();
    super.close();
    }
    }

     

    여기서 copyDatabase를 통해 asset폴더에 있는 sql 파일을 기기내의 디렉토리로 옮기고 그것을 바탕으로 쿼리문을 실행해서 검색을 수행하는 기가 막힌 작전이다.

     

    근데 아무리 해도 똥값만 나왔고 4만5천에 달해야할 행 수도 3개?밖에 없었다.

     

    직접 데이터를 열어보니 인코딩이 깨져서 쓸 수 없었다. 분명 UTF-8이 맞는데 원인을 알 수 없었다.

     

    그래서 일단은 엑셀에서 바로 불러오는 방법을 택했다. (기회가 되면 다시 sql 도전)

     

    엑셀을 바로 읽어들이는 방법은

    https://aries574.tistory.com/35

     

    대략 이런식으로 워크시트를 이용해서 불러오는 것이었다. 

     

    이중 for 문이 맘에 들지 않았다. 무엇보다 이미 json을 파싱해서 리사이클러 뷰로 나타내는 것을 구현해놨기 때문에

     

    엑셀 데이터를 json으로 변환했다. 이때 사용된 프로그램은 위에서 sql로 변환할때와 같은 DB browser for sqlite 이다.

     

    그 다음에 

    Asset 폴더에서 json 파일을 불러와서 String으로 반환하고

     

     

    String 형식의 json을 미리 만들어둔 클래스에 맞춰주고 검색해서 어댑터에 꽂아준다.

     

    검색기능은 Stream을 사용했는데 더 나은 방법이 있는지 모르겠다.

     

    아무튼 이런 방식으로 엑셀 데이터의 검색 기능을 구현했다. 생각보다 성능이 나쁘지 않았다. 0.5초안에 로딩 되는듯.

     

    아무래도 안드로이드는 이전에 계산기 만들어본게 전부라서 모든게 낯설고 새롭다.

    맨땅에 헤딩해가며 구현해나가는 중이다.

    visual description of header to the ground

     

     

    'Memo' 카테고리의 다른 글

    2021/10/26  (0) 2021.10.26
    현장실습 막바지 후기  (2) 2021.08.11
    현장실습 오티(첫출근) 후기  (1) 2021.06.26
    현장실습 관련  (0) 2021.06.17
    하계 현장실습 - 지원, 기업매칭, 면접  (1) 2021.05.25
Designed by Tistory.