반응형
반응형

안드로이드 스튜디오에서 AAR 파일 만들기





1. 안드로이드 스튜디오 프로젝트 오른쪽에 Gradle 아이콘 클릭





2. 클릭하면 화면이 이렇게 나오는데, AAR 파일을 만들 모듈 선택 후 Execute Gradle Task 클릭





3. aR 또는 AssembleRelease 입력 후 OK





4. 하단 Run 탭을 클릭하면, AAR 파일을 만드는 중~ 

오른쪽 하단의 Gradle Console 클릭 





5. build 완료 내용이 출력 확인





6. AAR 생성하려던 모듈 프로젝트/build/ouputs/arr/에 해당 arr파일 생성됨을 확인 가능!




* AAR 파일이란?

Android Archive package의 약자로 안드로이드 Lib용 압축 파일이다.

Java에서 사용되는 lib용으로 자주 사용되는 확장자는 Jar 파일인데, 안드로이드 스튜디오 프로젝트에서는 AAR 파일로 사용한다. 


참고 링크


반응형

안드로이드 스튜디오에서 SVN 사용하기


* 안드로이드 스튜디오 신규 프로젝트 생성 (Create new android studio project)
  1. File > New > New project
  2. Application name 지정 > Next
  3. Select the from factors your app will run on > Phone and tablet > IceCreamSandwich 4.0 > Next
  4. Activity 종류 선택 > Empty Activity > Next
  5. Activity Name 지정 > Finish
  6. 새로운 프로젝트 생성 중....
  7. 신규 프로젝트 생성 완료
* 안드로이드 스튜디오 SVN 초기 설정 (SVN 연결)
  1. https://www.visualsvn.com/downloads/ 에서 Apache Subversion command line tools 다운로드 
  2. 안드로이드 스튜디오 실행
  3. File > Settings > Subversion > General > Use command line client에서 svn.exe 파일로 경로 지정 > 저장
  4. 완료
* SVN 체크아웃 (Check-Out)
  1. File > New > Project form version Control > Subversion 선택
  2. Repositories + > Repository URL 입력 > OK 
  3. 해당 SVN 링크 옆에 ▶ 클릭 > 로딩 > SVN 계정 정보 입력 > 성공
  4. check-out 받을 프로젝트 폴더 위에서 > 마우스 오른쪽 > Check-out
  5. Destination Directory > 해당 프로젝트를 check-out 받을 경로 지정
  6. SVN Checkout Options > android-project path\trunk or 상위로 설정 > OK 
  7. Android Subversion working Format 1.8 기본 포맷 선택 후, 확인
  8. 완료
project check-out 후, 기존 gradle로 설정시
  1. Import Project > Import project from external model > Gradle 선택 > Next 
  2. Gradle Home setting > Use local gradle distribution > Finish
    1. gradle home path : android-studio\plugins\gradle
    2. 안드로이드 스튜디오 설치 파일에 함께 내장되어 있음
  3. 완료
project check-out 후, 새로운 프로젝트 생성시 
  1. create project from exstring sources > Next
  2. Project name과 Project location 확인 후 > Next 
  3. 계속 Next > Finish
  4. 'Schdule for Addtion, Do you want to schedule the following file for addtion to subverison?' .... '
  5. No - 
* SVN 커밋 (Commit)
  1. VCS > Commit Changes...
  2. Commit할 폴더 위에서 마우스 오른쪽 > Subversion > Commit DIrectory 
* SVN Sync 맞추기
  1. VCS > Update Poroject...
* 신규 또는 기존 프로젝트를 SVN에 Import하기
  1. SVN에 Import할 프로젝트 준비
  2. VCS > Import into Version Control > Import into Subversion
  3. Import할 Repositories 선택 > trunk > Import
  4. Import할 Project의 경로 지정 > OK
  5. Commit 메시지 설정 > OK
  6. SVN 버전 설정 > OK
  7. 완료
※ 안드로이드 스튜디오에서 SVN을 사용할 수는 있지만, 이클립스에서 사용하던 프로젝트를 안드로이드 스튜디오에서는 구동시킬 수 없다. 기존 프로젝트엔 gradle도 없고, 프로젝트 셋팅이 다르기 때문에 새롭게 해주어야 한다.

Import Error 

Cannot checkout from svn: svn E155000: '경로' is already a working copy for diffent URL.



관련 게시물

참고 링크


반응형

#안드로이드에서 로딩화면 구현하기

    • 방법1)LoadingActivity → MainActivity
    • 방법2)MainActivity → LoadingActivity → MainActivity


방법1) LoadingActivity → MainActivity

1) LoadingActivity 생성 

package com.example.n3815.new_app;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.os.Handler;

import com.example.n3815.new_app.assembly.AssemblyListActivity;


/**

 * Created by N3815 on 2017-01-31.

 */

public class LoadingActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_loading);

        startLoading();

    }

    /**

     * 로딩을 위한 메소드 구현 - 2초후에 이동

     */

    private void startLoading() {

        Handler handler = new Handler();

        handler.postDelayed(new Runnable() {

            @Override

            public void run() {

                Intent intent = new Intent(getBaseContext(), AssemblyListActivity.class);

                startActivity(intent);

                finish();

            }

        }, 2000);

    }

}


run() 부분에 시작할 Activity 설정


또는 

/**
 * Created by N3815 on 2017-01-31.
 */
public class LoadingActivity extends Activity {
    ArrayList<AssemBean> assemblyList = new ArrayList<AssemBean>(); // 전체 국회의원의 정보를 담는 객체
    // API 호출을 위한 Client
    DefaultRestClient<AssemblyService> restClient;
    // 국회의원 REST API URL SERVICE
    AssemblyService assemblyService;
    boolean isCall = false; // 호출이 되었는지 확인
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading);
        try {
            if(!isCall) {
                // 전체 국회의원 리스트 가져오기
                AssemblyList();
            }
        } catch (IOException e) {
            // 다시 요청시도 하기
            Toast.makeText(LoadingActivity.this ,"[Loading] Error(10003-요청 오류)",Toast.LENGTH_LONG).show();            
  e.printStackTrace();
        }
}
    /**
     * 국회의원 목록 가져오기 I/F
     */
    public void AssemblyList() throws IOException {
        isCall = true;
        restClient = new DefaultRestClient<>();
        assemblyService = restClient.getAssemblyClient(AssemblyService.class);
        Call<Items> call = assemblyService.getMemberCurrStateList(1, 300);
        call.enqueue(new Callback<Items>() {
            @Override
            public void onResponse(Call<Items> call, Response<Items> response) {
                try{
                    if(response.isSuccessful()){
                        // 전체 대상자 추가하기
                        for(AssemBean userInfo : response.body().getItems()){
                            // 초성정보 객체에 미리 넣어주기
userInfo.setInitialEmpNm(SearchCommon.getInitialSound(userInfo.getEmpNm().charAt(0)));
assemblyList.add(userInfo);
 }
 Log.v("[AssemblyListActivity]","[API 호출 성공]: "+assemblyList.size()); 
 Log.v("[AssemblyListActivity]","[Adapter에 전달]: 모든 국회의원 정보를 조회 완료하였습니다.");

 if(assemblyList.size() == 300){
        Intent intent = new Intent(LoadingActivity.this, AssemblyListActivity.class)
        intent.putExtra("assem", assemblyList);
        startActivity(intent);    
 }
                    }
}catch (Exception e){
                    Toast.makeText(LoadingActivity.this ,"[Loading] Error(10000-파싱 오류)",Toast.LENGTH_LONG).show();
                    e.printStackTrace();
                }
}
            @Override
            public void onFailure(Call<Items> call, Throwable throwable) {
                if(throwable instanceof SocketTimeoutException){
                    // 다시 요청시도 하기
                    Toast.makeText(LoadingActivity.this ,"서버가 불안정합니다. 다시 시도해주세요.",Toast.LENGTH_LONG).show();
                }else{
                    // 다시 요청시도 하기
                    Toast.makeText(LoadingActivity.this ,"[Loading] Error(10001-요청 오류)",Toast.LENGTH_LONG).show();
                }
                throwable.printStackTrace();
            }
        });
    }

주의할 것! finish()가 없을 경우, 뒤로가기 버튼 클릭시 로딩화면으로 다시 되돌아간다.


2) android Manifest.xml 파일에 시작 Activity 수정

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.n3815.new_app">

    <uses-permission android:name="android.permission.INTERNET"/>

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application

        android:name="android.support.multidex.MultiDexApplication"

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:supportsRtl="true"

        android:theme="@style/Theme.AppCompat.Light.NoActionBar">

        <activity android:name=".LoadingActivity" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        <activity android:name = ".SubActivity"/>

        <activity android:name = ".MainActivity"/>

        <activity android:name = ".list.ListActivity"/>

        <activity android:name = ".customList.CustomListActivity"/>

        <activity android:name = ".assembly.AssemblyListActivity"/>

        <activity android:name = ".assembly.AssemblyDetailActivity"/>

        <activity android:name = ".assembly.AssemblySearchActivity"/>

    </application>

</manifest>


시작 Activity를 LoadingActivity로 변경


방법2) MainActivity → LoadingActivity → MainActivity

나중에 정리하자.



참고 링크


반응형
package com.example.n3815.new_app.assembly;

import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.n3815.new_app.R;
import com.example.n3815.new_app.common.bean.AssemBean;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Locale;

/**
* Created by N3815 on 2016-12-28.
*/

public class AssemblyListAdapter extends BaseAdapter {
// Adapter에 추가된 데이터를 저장하기 위한 ArrayList
private ArrayList<AssemBean> assemblyItemList = new ArrayList<AssemBean>();

ArrayList<AssemBean> temp = new ArrayList<AssemBean>();

public AssemblyListAdapter(){
}

// Adapter에 사용되는 데이터의 개수를 리턴. : 필수 구현
@Override
public int getCount() {
return assemblyItemList.size() ;
}

// 지정한 위치(position)에 있는 데이터와 관계된 아이템(row)의 ID를 리턴. : 필수 구현
@Override
public long getItemId(int position) {
return position ;
}

// 지정한 위치(position)에 있는 데이터 리턴 : 필수 구현
@Override
public Object getItem(int position) {
return assemblyItemList.get(position) ;
}

// 데이터 정렬을 위한 Comparator
public static Comparator<AssemBean> cmpAsc = new Comparator<AssemBean>() {
@Override
public int compare(AssemBean o1, AssemBean o2) {
return o1.getEmpNm().compareTo(o2.getEmpNm()) ;
}
};

/**
* 어뎁터의 뷰를 구현하는 함수
* @param position -- 행의 index를 의미
* @param convertView -- 행 전체를 나타내는 뷰를 의미
* @param parent -- 어댑터를 가지고 있는 부모의 뷰를 의미
* @return
*/
@Override
public View getView(final int position, View convertView, ViewGroup parent) {

final Context context = parent.getContext();
ViewHolder viewHolder;
View v = convertView;

// getView에서 넘어오는 convertView는 이전에 그려졌던 view를 넘기는데요.
// 한번도 inflate되지 않은 view라면 null로 전달되는 경우가 있으니 반드시 null체크는 해야합니다.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.activity_assem_item, parent, false);

// 화면에 표시될 View(Layout이 inflate된)으로부터 위젯에 대한 데이터 획득
viewHolder = new ViewHolder();
viewHolder.imgView = (ImageView) v.findViewById(R.id.assem_empImg);
viewHolder.empNmView = (TextView) v.findViewById(R.id.assem_empNm);
viewHolder.origNmView = (TextView) v.findViewById(R.id.assem_origNm);
viewHolder.favoriteBtn = (CheckBox) v.findViewById(R.id.favorite);
viewHolder.colorView = (TextView) v.findViewById(R.id.color);
v.setTag(viewHolder);

// 즐겨찾기 버튼 클릭시
viewHolder.favoriteBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// [callback] 현재 선택된 객체 정보를 가져온다.
AssemBean selectedAssem = (AssemBean) view.getTag();
CheckBox selectedBtn = (CheckBox) view;

// 아이템을 클릭했을 경우,
if (selectedAssem.getFavorite() == false && selectedBtn.isChecked()){
Log.v("★[추가]★","======>>"+selectedAssem.getEmpNm());

// 객체의 정보를 true로 설정 - 자동으로 Array 배열의 값이 변경
selectedAssem.setFavorite(true);

for(AssemBean u : assemblyItemList){
Log.v("*[전체]*",":"+u.getEmpNm()+",("+u.getFavorite()+")");
}

// 현재 객체의 정보를 저장
view.setTag(selectedAssem);


temp.clear();
for(int q=0; q < assemblyItemList.size(); q++){
// assemblyItemList에 담긴 값이 즐겨찾기가 true일 경우
if(assemblyItemList.get(q).getFavorite()){
Log.v("*[temp에 add]*","======>>"+assemblyItemList.get(q).getEmpNm()+"("+q+")");
temp.add(assemblyItemList.get(q)); // 해당 객체 insert
assemblyItemList.remove(assemblyItemList.get(q)); // 해당 객체 delete
}else{
Log.v("*[X그외X]*","==>>"+assemblyItemList.get(q).getEmpNm()+"("+q+")");
}
}
// temp에 담긴 즐겨찾기 리스트 재정렬
Collections.sort(temp, cmpAsc);
for(AssemBean u : temp){
Log.v("#[즐겨찾기 정렬 중]#",":"+u.getEmpNm()+",("+u.getFavorite()+")");
}

// 맨 앞으로 이동
assemblyItemList.addAll(0, temp);
Log.v("===========","======================================>>>>>>"+assemblyItemList.size());
// assemblyItemList를 모두 찍어보기
for(AssemBean u : assemblyItemList){
Log.v("#[결과]#",":"+u.getEmpNm()+",("+u.getFavorite()+")");
}

notifyDataSetChanged();
Toast.makeText(context,"즐겨찾기가 등록 되었습니다.",Toast.LENGTH_LONG).show();

}else if(selectedAssem.getFavorite() == true){
Log.v("★[해제]★","======>>"+selectedAssem.getEmpNm());

selectedAssem.setFavorite(false);

// assemblyItemList를 모두 찍어보기
for(AssemBean u : assemblyItemList){
Log.v("*[전체]*",":"+u.getEmpNm()+",("+u.getFavorite()+")");
}
Log.v("*[전체 총개수]*",":("+assemblyItemList.size()+")");

temp.clear();

Collections.sort(assemblyItemList, cmpAsc);
for(int q=0; q < temp.size(); q++){
// 해당 정보가 false일 경우
if(assemblyItemList.get(q).getFavorite() && selectedAssem.getFavorite()){
Log.v("*[temp에 add]*","======>>"+assemblyItemList.get(q).getEmpNm());
temp.add(assemblyItemList.get(q));
assemblyItemList.remove(assemblyItemList.get(q));
}
}

// temp에 담긴 즐겨찾기 리스트 재정렬
Collections.sort(temp, cmpAsc);

// 맨 앞으로 이동
assemblyItemList.addAll(0, temp);

// assemblyItemList를 모두 찍어보기
for(AssemBean u : assemblyItemList){
Log.v("#[즐겨찾기 정렬 중]#",":"+u.getEmpNm()+",("+u.getFavorite()+")");
}

notifyDataSetChanged();
Toast.makeText(context,"즐겨찾기가 해제 되었습니다.",Toast.LENGTH_LONG).show();
}
}
});
}
// 캐시된 뷰가 있을 경우 저장된 뷰홀더를 사용한다
else{
viewHolder = (ViewHolder) v.getTag();
}

// Data Set(assemblyItemList)에서 position에 위치한 데이터 획득
final AssemBean listViewItem = assemblyItemList.get(position);
if(listViewItem != null){
// 현재 클릭한 아이템이 해당 객체에 들어가게된다.
viewHolder.favoriteBtn.setTag(listViewItem);

// 정당 색깔 구분
viewHolder.colorView.setBackgroundColor(Color.rgb(128, 128, 128));
if(listViewItem.getEmpNm().contains("강")) {
viewHolder.colorView.setBackgroundColor(Color.rgb(255, 0, 0));
}

// 각 위젯에 데이터 반영
Picasso.with(context).load(listViewItem.getJpgLink()).into(viewHolder.imgView);
viewHolder.empNmView.setText(listViewItem.getEmpNm());
viewHolder.origNmView.setText(listViewItem.getOrigNm());
viewHolder.favoriteBtn.setChecked(listViewItem.getFavorite());
}

return v;
}

/**
* 검색 기능
* @param charText -- 검색어
* @param assemList -- 국회의원 리스트
*/
public ArrayList<AssemBean> filter(String charText, ArrayList<AssemBean> assemList) {
charText = charText.toLowerCase(Locale.getDefault());
assemblyItemList.clear(); // 어뎁터 뷰에 연결된 배열 초기화

Log.v("***","전체 대상자 :"+assemList.size()+", (검색어 :"+charText+")***");

if (charText.length() == 0) {
// 검색된 글자가 하나도 없을 경우, 전체 리스트를 넣어주기
assemblyItemList.addAll(assemList);
} else {
// 검색된 글자가 있을 경우, 검색어와 일치하는 국회의원 정보를 담아주기
for(AssemBean u : assemList){
String name = u.getEmpNm(); // 국회의원 이름
if (name.toLowerCase().contains(charText)) {
Log.v("*[확인]*","일치하는 국회의원 :"+name);
assemblyItemList.add(u);
}
}
}

return orderByAssemList(assemblyItemList);
}

/**
* 대상 배열을 재정렬해줍니다.
* @param targetArray
*/
public ArrayList<AssemBean> orderByAssemList(ArrayList<AssemBean> targetArray){

// 전체정렬
Collections.sort(targetArray, cmpAsc);
Log.v("===========","========================================");

// 즐겨찾기 골라서 맨위로
ArrayList<AssemBean> temp = new ArrayList<AssemBean>();
for(int j = 0; j < targetArray.size(); j++){
if(targetArray.get(j).getFavorite() == true){
temp.add(targetArray.get(j));
targetArray.remove(j);
}
}
Collections.sort(temp, cmpAsc);
targetArray.addAll(0, temp);

notifyDataSetChanged();

return targetArray;
}

public class ViewHolder
{
public int number;
ImageView imgView;
TextView empNmView;
TextView origNmView;
CheckBox favoriteBtn;
TextView colorView;
}

}


반응형

#안드로이드 스크롤뷰 사용법 (Android scrollview)



// 스크롤 - 스크롤 처리에 대한 부분

listview.setOnScrollListener(new AbsListView.OnScrollListener() {

    @Override

    public void onScrollStateChanged(AbsListView absListView, int i) {

        // 상태에 대한 콜백 메소드

    }

    @Override

    public void onScroll(AbsListView absListView, int i, int i1, int i2) {

        // 스크롤 행위에 대한 콜백 메소드


        // 데이타가 정상적으로 다 보여졌을 때

        if (absListView.isShown()) {

            // 마지막 아이템까지 모두 보았을 경우, 페이지 추가 로드

            if(totalItemCount != 0 && (firstVisibleItem+visibleItemCount) == totalItemCount && lastitemVisibleFlag == false) {

                try {

                    // 다음 페이지 로드하는 비즈니스 로직 처리

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }

    }

});


반응형

#LinearLayout : https://developer.android.com/reference/android/widget/LinearLayout.html

  • Relative와 다르게 LinearLayout은 각 Obj들이 서로 중첩되지 않는다.
  • 특정 Obj기준으로 View Layout을 쌓는 느낌이다. 


1. 프로필 사진 레이아웃

<!-- 1번 레이아웃 -->

<LinearLayout
android:layout_height="60dp"         // 높이(세로)
android:layout_width="60dp"          // 길이(가로)
android:layout_marginLeft="10dp"     // 왼쪽 마진
android:orientation="vertical">      // 정렬 여부


<ImageView
android:id="@+id/assem_empImg"     // ImageView 아이디
android:layout_width="60dp"        // 길이(가로)
android:layout_height="60dp"/>     // 높이(세로)

</LinearLayout>

2~4. 상세정보 레이아웃

<!-- 내용 -->
<LinearLayout
android:layout_width="200dp"    
android:layout_height="60dp"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/assem_empImg"     // 1번 프로필 사진(assem_empImg) 오른쪽에 정렬

android:orientation="vertical"                    // 세로 정렬!
android:weightSum="1">        // 하위 뷰에 대해서 가로에 대해서 상대적인 비율을 주기 위한 옵션

<!-- 2, 3번 레이아웃 -->
<LinearLayout
android:layout_width="200dp"
android:layout_height="25dp"
android:layout_toRightOf="@+id/assem_empImg"    // assem_empImg 오른쪽에 정렬
android:orientation="horizontal"       // 2번 3번 obj를 붙이기 위한 가로 정렬
android:weightSum="1">
            
<TextView
android:id="@+id/assem_empNm"      // textView의 ID 설정
android:layout_height="25dp"    
android:layout_width="50dp"
android:layout_gravity="top"       // 정렬은 LinearLayout의 top에 붙이기
android:textSize="12sp"            // 폰트 사이즈 12sp
android:textStyle="normal|bold"/> // 텍스트 스타일 : 굵게

<TextView
android:id="@+id/assem_dang"       // textView의 ID 설정
android:layout_width="140dp"
android:layout_height="25dp"
android:layout_toRightOf="@+id/assem_empNm" // assem_empNM의 오른쪽에 정렬
android:layout_gravity="top"           // 정렬은 LinearLayout의 top에 붙이기
android:textSize="12sp"                
android:textStyle="normal|bold"
android:layout_marginLeft="10dp" />       
</LinearLayout>

         <!-- 4번 레이아웃 -->
<TextView
android:id="@+id/assem_origNm"
android:layout_weight="0.22" // 하위 뷰에 대해서 가로에 대해서 상대적인 비율을 주기 위한 옵션
android:layout_height="25dp"
android:layout_width="200dp"
android:layout_gravity="bottom"    // LinearLayout의 바닥에 정렬

android:textSize="12sp"
android:layout_marginTop="10dp"
android:textStyle="normal|bold"
android:textAlignment="center" />        // 텍스트 정렬은 가운데

</LinearLayout>

5. 즐겨찾기 레이아웃

  <!-- 5번 레이아웃 -->

<LinearLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:weightSum="1"
android:layout_marginRight="10dp">

<ToggleButton
android:id="@+id/favorite"
android:layout_width="60dp"
android:layout_height="60dp"
android:textOff="OFF"              // 꺼졌을 때, 텍스트 정의
android:textOn="ON"                // 켜졌을 때, 텍스트 정의
android:src="@drawable/favorite_stat"/>    // 토글 버튼의 style 지정

</LinearLayout>


참고 링크


반응형

# Layout Inflater : https://developer.android.com/reference/android/view/LayoutInflater.html

안드로이드에서는 화면을 구성하는 방법으로  xml 레이아웃을 사용하는데, 이 xml 레이아웃 파일의 내용은 애플리케이션이 실행될 때 메모리로 로딩되어서 객체화 된다. xml 레이아웃에 정의된 내용을 메모리 상에 객체화되는 과정을 '인플레이션(inflation)' 이라고 한다. 

즉, xml 레이아웃 파일은 프로젝트가 빌드되는 시점에 이진 파일로 컴파일되어 애플리케이션에 포함되긴 하지만, 

실제로 실행시점이 되어서야 메모리에 로딩되어 객체화가 된다는 말이다.


예제 1)

onCreate(bundle saveInstanceState){

super.onCreate(saveInstanceState);


// 버튼 호출

setContentView(R.layout.activity_main); 

}

setContentView전에 button을 호출하게 된다면 당연히 오류가 난다. 

메모리상에 객체화 (로드) 되지 않은 데이타를 호출하려고 했기 때문에 오류가 나면서 애플리케이션이 중지된다.


즉, setContentView() 메소드의 역할은

  1. 화면에 나타낼 뷰를 지정
  2. xml 레이아웃의 내용을 메모리상에 객체화

그렇다면, 화면 전체에 나타낼 xml 레이아웃이 아니라 전체 화면 중에서도 일부분만 차지하는 화면 구성 요소들을 xml 레이아웃에서 로딩하여서 보여줄 순 없을까? 있다. 다만, 다른 메소드를 사용해야한다.  layoutInflater 라는 클래스를 사용하여서 해야한다. (페이지 216~)


예제 2)

getSystemService(Context.LAYOUT_INFLATER_SERVICE)

이렇게 layoutInflater를 참조시킨 후에 사용이 가능하다. 


참고 링크

  • 안드로이드 앱 프로그래밍
  • 안드로이드 개발자 센터 


반응형

#액티비티 (Activity) : https://developer.android.com/reference/android/app/Activity.html





안드로이드 생명주기 사용법

public class Activity extends ApplicationContext {

     protected void onCreate(Bundle savedInstanceState);

     protected void onStart();

     protected void onRestart();

     protected void onResume();

     protected void onPause();

     protected void onStop();

     protected void onDestroy();

 }

생명주기 메소드에 대한 설명

  1. onCreate()
    • Activity  초기화 및 화면 설정
  2. onRestart()
    • App이 재시작될 때 호출되는 함수로, onStart() 직전에 호출
  3. onStart()
    • 액티비티가 사용자에게 보이기 직전에 호출
  4. onResume()
    • 사용자와 상호작용을 하기 전에 호출되는 함수
    • Activit 스택의 맨 위에 있어서 Activity가 사용자에게 보여지고, 사용자의 입력을 처리할 수 있을 때 호출
  5. onPause()
    • 다른 Activity가 호출될 때 호출된다. 
    • 데이터 저장 및 스레드 중지 등의 처리를 하기에 좋은 메소드
  6. onStop()
    • 더이상 Activity가 스택의 최상 위에 있지 않을 때 즉, 사용자에게 보이지 않게 될 때 호출
    • 메모리가 부족할 경우, onStop() 메소드가 호출되지 않을 수도 있다.
  7. onDestory()
    • Activity를 종료/소멸될 때 호출
    • finish() 메소드가 호출되거나 시스템이 메모리 확보를 위해서 액티비티 제거시 호출됨



+ Recent posts