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

[오프라인 DATA 구현방법]

0 추천
[오프라인 DATA 구현방법] Firebase Database의 setPersistenceEnabled() 이 기능을 구현하는 방법.

 

 

firebase datebase를 쓰지 않고

개인 앱서버에서 data를 받아오고 있습니다.

인터넷이 불가능한 상황에서는 당연히 아무 데이타도 나오지 않습니다.

 

Activity 호출시 기존에 받았던 데이터를 갖고있다가

인터넷 연결 유무와 관계없이

그대로 출력해주도록 구현하고자하는데..

 

어떤 키워드로 검색을 해야

이런 부분에 대한 정보를 알 수 있는지요?

 

(변수에 static으로 저장하는 건 불안정하다고 하니 그 외의 방법을 알려주시길 부탁드립니다.. ^^)
목마른어린양 (960 포인트) 님이 2017년 7월 16일 질문

2개의 답변

+1 추천
 
채택된 답변

훌륭한 질문입니다. 서비스는 안정적으로 동작해야 합니다. 당연히 좋은 앱들은 오프라인 모드를 고려하죠. 운동앱인데, 서버에 업로드하려고 하는데 음영지역이면? 날려버릴 건가요? 당연히 그렇게 하면 안됩니다.

서버에서 데이터를 받아서 받은 데이터를 그대로 파일로 저장합니다. 그리고 기존처럼 처리하죠.

서버에 데이터를 받아올 때, Internet이 안되면, 파일을 읽어 옵니다.

json이라면, gson을 사용하면 간단하게 파일에 저장하고, 파일에서 객체를 읽어 올 수 있습니다.

Data Model를 사용한다면, 객체에 담고, 객체를 저장하거나, 파일에서 객체를 불러오는 방식을 사용해도 됩니다. (저의 경우는 이 방시을 사용했죠. 서버로 데이터를 업로드할 때 인터넷이 안되거나 통신에 오류가 나면, 파일로 저장해 두고, 다음에 접속했을 때 올리는 형태로 안정적으로 구현합니다.)

중요한 것은 서버에서 가져올 때 쿼리 파라미터가 어떤 거냐에 따라서 같은 Request라도 몇개를 보관할 것이냐가 문제가 되겠죠.

만약에 서버에서 가져오는 것은 아주 심플하거나 파라미터가 거의 유사하다면 크게 문제될 것이 없습니다.

아래는 와이파이던, 블루투스던, 이통사 네트워크던 인터넷이 되어 있는지 확인하는 코드입니다.

// 어떤 네트워크던 연결되어 인터넷이 되는지 확인용.
public static boolean isNetworkAvailable(Context ctx) {
    ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = cm.getActiveNetworkInfo();
    if (networkInfo == null) return false;
    return networkInfo.isConnected();
}

 

아래는 Object Instance를 Gson으로 저장하는 로직입니다. (objReceived는 클래스의 인스턴스입니다. 통신한 뒤에 객체에 저장된 놈이죠. Retrofit2 같은 걸 쓰면 json 같은 데이터는 자동으로 객체에 들어가므로, 그걸 그냥 파일로 저장하면 됩니다. 반대도 있습니다. gson.fromFile인가 그래요. 구글링하면 금방 나옵니다.)

        if (objReceived != null) {
            Gson gson = new Gson();
            String gsonStr = gson.toJson(objReceived);
            writeToFile(filePath, gsonStr);
        }

훌륭한 질문이라고 했던 것은,

개발을 하면서 드는 이런 질문들을 포기하지 말고 끝까지 구현해 나가기를 바라는 의도입니다.

이런 질문들이 없었다면, 훌륭한 개발자들이 나오지 않았겠죠.

이렇게 드는 질문들을 지금 하시는 프로젝트 기간안에 구축하려고 노력하는 바로 그 순간이 훌륭한 개발자인 것입니다. 10년 20년을 코딩했다고 훌륭한 개발자가 되는 게 아닙니다. :) 즉 훌륭한 개발자는 지금 그순간에 진행중인 것이지, 완성되는게 아닙니다. 질문을 멈추는 순간, 꼰대 개발자가 되는 거죠. 

글을 쓰면서도 찔리네요. :)

 

 

Will Kim (43,170 포인트) 님이 2017년 7월 19일 답변
목마른어린양님이 2017년 7월 20일 채택됨
우와....
상세한 답변. 정말 감사드립니다.

저는 asynchttpclient를 이용하여 json을 gson으로 변환해서뿌려주고 있습니다.
Retrofit2를 써야겠네요..

그럼 Image는 url로 받아서 디바이스 저장소에 바로 저장해서 그 URI주소를 저장해놨다가 써야 되겠네요..?
잘 알겠습니다.

------------------------------------
처음에 sharedPreference 여러개 만들어서 저장하려고 했었는데 그건 정말 무식한 방법이었네요..
막연하게 File로 만들어야 한다고만 생각했는데 설명을 들으니 뭘 찾아봐야 할지 명확해졌습니다.

남들 다 아는 거 나만 몰라 하루에도 수번씩 드는 자괴감으로 포기를 몇 번이고 했던 프로젝트인데 이렇게 한소리 들으니 제 자신을 다시금 채근하게 됩니다.

저번 질문때도 상세한 도움을 받았었는데..
감사한 마음을 표현할 길이 없네요.
복 받으실 겁니다.
그럼 다음번에는 더 훌륭하고 심오한 질문을 준비해 보겠습니다. ^^;
감사합니다.
+1 추천
원격지 DB에 직접 접근하는것은 보안상 위험이 있으니,

C#인 경우 IIS 또는 ASP.NET 을 찾아보셔서 DB에서 데이터를 읽어올 서비스를 만드시는것이 좋고,

Linux 또는 Unix 인 경우에는 php를 사용하여 DB에서 데이터를 읽어올 수 있도록 하시는것이 좋습니다.

FTP를 사용하여 파일 형태로 다운로드 하는 방식을 사용할 수도 있습니다.

다만, 크롤러나 다른 매체에서 마음대로 긁어가지 못하도록 접근 키를 추가해주시는 것이 좋습니다.

데이터를 읽어오기 위해 HttpRequest 쪽을 좀 보셔야 할 것이고,

읽어온 데이터를 로컬에 저장하기 위해서는 SQLite 또는 파일 I/O 를 찾아보셔야 하셔야할 것 같습니다.

데이터를 갱신하기 위해서는 Foreground 로 읽는 것도 좋겠지만 사용자에게 데이터 로딩 완료까지 기다려야 하는 시간이 추가되므로, 앱이 실행될 때 Background에서 다운로드 또는 갱신을 완료한 후 Broadcast로 액티비티에 전달하는것이 더 좋은 방법일 것 같습니다.
스컬트 님이 2017년 7월 17일 답변
전반적인 개념에 대한 설명 감사합니다.
Background로 다운 받아서 Broadcast로 전달한다는 부분은 좀 더 찾아봐야 겠습니다.

대단히 감사합니다.
복 많이 받으실 겁니다.
...