[Kotlin Logo]


안드로이드 뿐만 아니라 코드를 작성하다보면 보일러플레이트 코드가 생기기 마련이다.

예를들면 Java에서 Getter, Setter를 추가 한다던지, 안드로이드에서 findViewById를 사용한다던지..

반복되는 작업이지만 안할 수도 없는 것들이라 언제나 고민거리다. 하지만 나의 생각은 또 다른 누군가의 생각인 법!

이를 해결하기 위해 다양한 언어에서 다양한 방법이 나와있으니, 꼭 사용하여 반복되는 코드를 피할 수 있으면 피하는 것이 좋다.


안드로이드를 기준으로 Java에서는 Lombok과 ButterKnife의 어노테이션을 사용하여 위의 코드들을 제거할 수 있다.

코틀린에서는 data class와 kotlin android extensions(synthetic)를 사용하여 제거가 가능하다. (butterKnife -> kotterKnife도 있음)



이제 본론으로..예제

오늘은 코틀린에서 XML을 템플릿 처럼 사용하는 방법을 알아보려고 한다.

[toolbar의 title을 사용하지 않고 toolbar 내부에 textView를 넣어 textView의 값을 변경하는 예제]


1. toolbar.xml (템플릿처럼 사용 할 toolbar layout)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="4dp">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:minHeight="?attr/actionBarSize"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetRight="0dp"
app:contentInsetEnd="0dp" >

<TextView
android:id="@+id/toolbar_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/toolbar_title"
android:textColor="@color/md_black_1000"
android:textSize="18sp"
android:textStyle="bold" />

</android.support.v7.widget.Toolbar>
</android.support.v7.widget.CardView>

2. MainActivity.kt

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.toolbar.*

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

toolbar_title.text = "제목이 들어갑니다."

}
}

3. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<include
android:id="@+id/topView"
layout="@layout/toolbar" />

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/topView">

</android.support.v7.widget.RecyclerView>
</RelativeLayout>


toolbar.xml을 만들어두고 사용할 화면에서 <include>를 해준 다음 Activity코드에서 toolbar.xml로 바로 접근이 가능하다.

toolbar의 설정을 변경하고 싶으면 toolbar.xxx , 내부에 textView를 변경하고 싶으면 toolbar_title.xxx 

물론 recyclerView도 바로 접근이 가능하여 recyclerView.xxx를 사용할 수 있다.

(일반적인 자바로 작성했었다면 findViewById ... toolbar ... recyclerView....... 이제 findViewById는 잊어도 된다.)


이와 비슷한 방법으로 Button을 만들어두고 Style을 지정하여 xml로 만들어두면 반복잡업 뿐만 아니라 다양한 어플리케이션에서도 활용할 수 있으니 얼마나 편한가!

또한 이러한 작업을 해두면 똑같은 버튼이라도 1px, 1dp가 다른 버튼이 생겨 전체의 틀이 망가지는 일을 없어 더욱 더 깔끔한 앱이 나올 것이다.


[Issue] "Unable to create Debug Bridge"


Dev&Prog/Android

Written by 블럭 on 2016. 4. 1. 19:06

Issue


Android Studio 2.1 Preview 4~5 를 설치 직후 다음과 같은 이슈가 발생하였다. 


Unable to create Debug Bridge: Unable to start adb server: Unable to obtain result of 'adb version'



Solution


1. 터미널에 접속하여 안드로이드가 설치 된 폴더 ( sdk - platform-tools )로 이동한다.

2. adb tcpip 5555를 입력한다. 

3. 안드로이드 스튜디오를 재시작한다. 

4. 정상적으로 작동된다.


참고한 주소 : http://stackoverflow.com/questions/33557845/android-studio-show-the-dialog-unable-to-create-debug-bridge-unable-to-start



아래 목록 중 한가지라도 해당이 된다면 이 포스팅의 내용이 해결책이 될 수 있음.

1. Fatal Signal 6 (SIGABRT) 
2. 
android INVOKE_INTERFACE || instr_code == Instruction::INVOKE_INTERFACE_RANGE Unexpected call into interface trampoline: invoke-virtual
3. ART Runtime ArrayIndexOutOfBoundsException
4. Retrofit을 사용중인 경우.

.........

이번 오류는 Retrofit과 gradle version으로 인한 것으로, Retrofit interface를 사용하여 rest통신을 실행할 때 예외가 발생하였다.
주 된 오류는 다음과 같다.

A/art: art/runtime/thread.cc:1344] Throwing new exception 'length=248; index=1273' with unexpected pending exception: java.lang.ArrayIndexOutOfBoundsException: length=248; index=1273

Check failed: count_ == 0 (count_=-1, 0=0) Attempted to destroy barrier with non zero count
A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 21705

위와 같은 오류가 발생한다면 다음의 사항을 의심해보아도 좋다.


1. Retrofit을 사용중이거나 최근에 버전을 업데이트 하였음.
2. Android Project Level의 Build.gradle 내용 중 com.android.tools.build:gradle:x.x.x 의 버전을 수정하였다.

해결책

from classpath 'com.android.tools.build:gradle:2.0.0-alpha8' to classpath 'com.android.tools.build:gradle:2.0.0-alpha3' // 2.0.0-alpha3 이하 버전으로 수정.


안드로이드를 개발하면서 많이 보게되는 deprecated.. 이전버전에서 지원하였지만 문제나 최신 API로 인하여 더 이상은 필요가 없는 경우에 이클립스에서 Notification 이런식으로 취소선을 쫙 그어준다.

이번에 처음으로 제대로 된 어플을 제작하는데 출시 마무리단계에서 좀 더 완벽해지고 싶은 마음에 눈에 거슬리는 노란색 느낌표들 모두를 제거하기 위해 deprecated를 제거해보았다.

이번 포스팅의 목표는 안드로이드 알림창인 Notification Class의 메소드인  Notification(icon, message, when)을 변경해보는 것이다.

기존 소스 코드
...(Context context, String message){
int icon = R.drawable.logo; 
long when = System.currentTimeMillis();
NotificationManager notificationManager =(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent nIntent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, nIntent, 0);
notification.setLatestEventInfo(context, title, message, pIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(1234, notification);      
}


수정 소스 코드
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle("제목")
.setContentText("내용")
.setSmallIcon(R.drawable.ic_angle)
.setTicker("상태바제목")
.setAutoCancel(true)
.build();
notificationManager.notify(1234, notification);

두 코드의 메소드가 있고 없고 차이는 상관없음. ( 알림 하나 만들어두려면 수정 코드 처럼 정의해두고 Push처럼 Message를 전송하려면 메소드 정의해서 호출 후 notify하는 식으로 ...)

기존 코드에서는 Notification을 생성하며 정의 된 icon, message, when을 넣은 반면,
수정 코드에서는 Notification Builder를 이용하여 필요한 설정을 넣어주는 식이다.딱 봐도 훨씬 간결하고 수정하기 쉬워 보인다.


참조 
Notification - http://developer.android.com/reference/android/app/Notification.html
Intent - http://developer.android.com/reference/android/content/Intent.html
Context http://developer.android.com/reference/android/content/Context.html


학교 시간표 모듈을 제작하면서 중복되는 시간을 제거해주는 버튼을 만들었는데
for문을 사용해서 탐색하는 시간이 너무 오래 걸렸다.

어디선가 보았는데 자바스크립트를 사용하면서 걸리는 최대시간이 0.1초여야 한다고 한다.
생각해보니 JSON으로 파싱하여 데이터 받아오고 실시간으로 검색어 뿌려주는데 본래의 빠르게 데이터를
주고 받으려는 목적을 벗어난거 같아서 DOM 구조를 이용하기로 했다.

jQuery의 find()를 이용하면 DOM Tree 를 따라 특정 값을 모두 검색하여 출력이 가능하다.

변경 전

for(i=0;i<splitTime.length;i++){ // 자른 문자배열의 길이만큼
    for(j=0;j<$("table input").length;j++){ // 인풋의 갯수만큼
    }

변경 후

for(i=0;i<splitTime.length;i++){ // 자른 문자배열의 길이만큼
    $("table").find("input[value="+splitTime[i]+"]").~  // table의 input중 splitTime[i]의 값을 모두 찾는다.
}

변경 후 속도가 월등하게 개선 되었음

(등록 된 시간표의 시간 갯수) * (인풋의 갯수 * 등록 가능한 시간표) -> (등록 된 시간표의 시간 갯수)

JSON accumulrate와 Put의 차이


Dev&Prog

Written by 블럭 on 2013. 12. 31. 11:05

 

JSON accumulrate와 Put의 차이 그리고 element ...?

Json 연습중 accumulate, put, element가 있어서 사용해보았는데
accumulate는 데이터에 Null값은 제외하고 담는 반면
Put은 Null값도 전부 담아주는 것 같다.
그리고 element와 accumulate
element는 요소에 데이터를 집어넣는 것으로 "test", "value"의 값을 집어넣으면 test를 while로 돌려도
최종적인 값이 들어가게 된다.
accumulate는 '축적하다'라는 뜻으로 말그대로 "test", "value"의 값을 집어넣으면 test를 while로 돌렸을 때
5회 수행시 최정적인 값은 value가 5번 들어간 값이 된다.

안드로이드 내장 DB 접근


Dev&Prog/Android

Written by 블럭 on 2013. 12. 24. 17:09

cmd -> adb shell -> su -> 권한획득 확인 -> chmod 777 /data -> DDMS data 폴더 접근

1시간동안 삽질했는데 결론은 루팅 된 폰에서만 접근 가능한 것 같다..............
내장 DB 배워보려고 했는데 초반부터 시간만 잡아먹었다.

이번학기에 배운 JAVA 언어를 이용하여 동일한 기능의 프로그램 세 가지를 작성해본다.
1. JAVA GUI
2. Android
3. JSP

세 가지 모두 하나의 Filtering class를 HashMap으로 구현하여 작성했다.

 

1. JAVA GUI

 

2. Android

 

3. JSP


예전에는 안드로이드 어플리케이션을 만들때 무작정 외워서 했지만
이번학기에 JAVA를 배우고나니 안드로이드가 이렇게 쉬운줄은 몰랐다.
아직은 시작에 불과하지만 내가 생각하는게 모두 구현될때까지 더더 열심히 공부해야겠다.

 

[DB모델링] Cafe de Horang / 2학기 팀 프로젝트


Dev&Prog

Written by 블럭 on 2013. 12. 2. 18:52

이번 2학기 과목중 하나로 데이터베이스모델링을 수강했다.
학기가 끝나가며 DB 실습 팀프로젝트를 내주셨고 우리 팀은 JSP를 이용한 웹페이지를 이용하여
약간의 시뮬레이션이 포함 된 커피숍 홈페이지를 제작하기로 했다.

1차로 요구사항을 수집 개념적 논리적 설계를 하고 2차로 쿼리를 짜본다음 3차로 JSP 연동을 했는데
처음 접한 DB설계라 어려움이 많았지만 팀원이 꽁꽁 뭉쳐 서로 피드백을 하다보니 깔끔한 데이터 베이스와 페이지가 만들어졌다.

 나름 JSP를 확실하게 사용하려고 세션도 넣고 디자인과 코드부분도 나눠 깔끔하게 짜보았다. css, js, jsp 구분!
디자이너가 아니라 완벽한 디자인은 나오지 못했지만 틀은 어느정도 잡힌 것 같아서 뿌듯하고 완성도가 매우 높다고 생각하여 만족스럽다. 

 

[JSP] JSP&서블릿, 기본 셋팅


Dev&Prog/JSP

Written by 블럭 on 2013. 11. 30. 11:47

JSP(JavaServerPages)는 웹 브라우저의 요청을 받아 해당하는 웹 페이지를 찾아서 보내주는 Web server다.
이 웹 서버는 웹 브라우저로부터 URL을 받아서 그에 해당하는 문서를 찾아 웹 브라우저로 보내주는 일을 한다.

JSP는 기본적으로 JAVA프로그래밍은 이해해야하고 HTML을 많이 써본 사람이라면 코딩하는데 어려움이 없을 것 같다.
- HTML문서 안에 자바 코드가 삽입되는 구조이기 때문에...
(초등학교 3학년 때 재밌다고 다음 카페 태그교실에서 배운게 지금도 많은 도움이 되고있다!)

JSP는 기본적으로 <% %>, <%= %> 등으로 사용을 하지만 JSP2.0에서 추가 된 EL(ExpressionLanguage)을 사용하여
자바코드를 제거해 코드가 간결하고 가독성을 좋게 할 수 있다. 최근에는 자바코드를 이해할 필요가 없는 디자이너와의 협업이 많아지면서 JSP문에 자바코드를 제거하여 작성하는 곳이 많다고 한다. JSTL, JavaBean 등...

Servlet 자바를 기반으로 하는 웹 애플리케이션 프로그래밍 기술이다.
서블릿은 자바 클래스 형태로 작성이 되며 이렇게 작성 된 클래스는 서블릿 클래스라 부른다.
서블릿은 자바코드 안에 HTML 문이 삽입 된다.

*서블릿 클래스를 작성할 때의 규칙*
1. javax.servlet 패키지에 속하는 Servlet 인터페이스를 구현하도록 만들어야 한다.
- import Servlet.http.*;  후 HttpServlet을 상속하여 사용하는게 편함
2. doGet 이나 doPost라는 메서드를 선언하고, 그 안에 서블릿 클래스가 호출되었을 때 해야할 일을 써 넣어야 한다.
- 파라미터로는 HttpServletRequest request, HttpServletResponse respone가 들어간다.
3. 동적인 HTML 문서 생성을 위해 doGet이나 doPost 메서드의 두 번째 파라미터 파라미터를 이용해야 한다.

-서블릿 클래스 작성 예제-

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*; 
public class ServletTest extends HttpServlet{
    public void doGet(HttpServletRequest request, HttpServletResponse response) 
                            throws ServletException,    IOException{
    PrintWriter out = response.getWriter();
    out.println("<HTML>");
    ......
    out.println("</HTML>");
    }     
}

이제 코드를 작성하여 테스트를 할 서버를 만들어 보자.(톰캣과 이클립스를 이용하여 작성)
준비물 - Tomcat 6.0 / JDK SE / Eclipse EE
톰캣 6.0 - http://tomcat.apache.org/download-60.cgi
>> 32-bit/64bit Windows Service Installer 클릭하여 다운로드
JDK - http://www.oracle.com/technetwork/java/javase/downloads/index.html
>> JDK DOWNLOAD - Java SE Development Kit에서 Accept 자신의 OS와 맞는 exe파일 다운로드
Eclipse - http://www.eclipse.org/downloads/
>> Eclipse IDE for Jave EE Developers 오른쪽에 자신의 OS에 맞게 클릭하여 다운로드

설치는 간단히 다음 다음을 눌러주면 되며 JDK의 별도의 환경변수 설정은 필요없으나
Eclipse EE를 실행 후 Window - Preferences - Runtime Environments 에서 Add - Apache Tomcat v6.0을 추가해야한다.

셋팅이 모두 끝났으면 이클립스에서 New - Dynamic Web Project 로 프로젝트를 생성한다.
(마지막 창에서 Generate web.xml이 체크 되어있나 확인)
프로젝트가 생성되었으면 ProjectName - WebContent안에다 jsp 파일을 생성 후 Run As를 눌러서
http://localhost:8080/ProjectName/FileName.jsp 가 하얀색 화면으로 뜨면 성공이다.

JSP 스터디를 하면서 배웠던 내용을 복습하는 겸 블로그에 적어봤는데 스쳐지나간 내용이나 자칫하면 까먹을 뻔했던 내용이 이제는 내 머리속에서 깔끔하게 정리 되었다.