웹사이트 검색

Android 인터뷰 질문 및 답변


Android는 휴대 전화에서 가장 널리 사용되는 운영 체제입니다. 요즘 Android 앱이 매우 인기가 있습니다. Android는 오픈 소스이기 때문에 매우 인기가 있으며 누구나 Android 앱을 만들 수 있습니다. Android 앱을 만드는 데만 전념하는 회사가 많이 있습니다. 나는 안드로이드 튜토리얼에 대해 많이 썼는데, 여기서는 인터뷰에서 당신을 돕기 위해 몇 가지 중요한 안드로이드 인터뷰 질문을 나열하고 있습니다.

Android 인터뷰 질문

활동과 AppCompatActivity의 차이점은 무엇입니까?\nAppCompatActivity는 애플리케이션 전체에서 일관된 기본 ActionBar 지원을 제공합니다. 또한 SDK 버전 7까지 다른 머티리얼 디자인 구성 요소에 대한 이전 버전과의 호환성을 제공합니다(ActionBar는 SDK 11부터 기본적으로 사용 가능함). 활동 확장은 이들 중 어떤 것도 제공하지 않습니다. 참고: SDK 21부터는 기본적으로 모든 활동이 AppCompatActivity를 확장합니다.\n\n\n활동, AppCompatActivity, FragmentActivity 및 ActionBarActivity. 그들은 어떻게 관련이 있습니까? 활동은 기본 클래스입니다. FragmentActivity는 활동을 확장합니다. AppCompatActivity는 FragmentActivity를 확장합니다. ActionBarActivity는 AppCompatActivity를 확장합니다. FragmentActivity는 프래그먼트에 사용됩니다. 지원 라이브러리의 빌드 버전 22.1.0부터 ActionBarActivity가 더 이상 사용되지 않습니다. appcompat-v7의 기본 클래스였습니다. 현재 AppCompatActivity는 지원 라이브러리의 기본 클래스입니다. ToolBar, 착색 위젯, 머티리얼 디자인 색상 팔레트 등과 같은 많은 새로운 기능을 제공합니다.\n\n\nAndroid 지원 라이브러리는 무엇이며 권장되는 이유는 무엇입니까? Android 플랫폼은 선택할 수 있는 다양한 버전과 장치를 지원합니다. 새로운 버전이 출시될 때마다 새로운 Android API가 추가되고 발전합니다. 이전 장치의 사용자가 이러한 새로운 Android API를 사용할 수 있도록 Android 지원 라이브러리가 설계되었습니다. Android 지원 라이브러리는 이전 프레임워크 릴리스와 호환되는 최신 API를 개발자에게 제공합니다.\n\n\nAndroid 지원 라이브러리의 구조에 대해 설명하시오.\nAndroid 지원 라이브러리는 단일 라이브러리가 아닙니다. 이름 지정 규칙과 용도가 다른 라이브러리 모음입니다. 더 높은 수준에서 세 가지 유형으로 나뉩니다.\n\n호환성 라이브러리: 이전 프레임워크가 최신 릴리스를 활용할 수 있도록 백 포팅 기능에 중점을 둡니다. 주요 라이브러리에는 v4 및 v7-appcompat가 포함됩니다. v4에는 DrawerLayout 및 ViewPager와 같은 클래스가 포함되며 appcompat-v7은 ActionBar 및 ToolBar를 지원하는 클래스를 제공합니다.\n구성 요소 라이브러리: 여기에는 다른 지원 라이브러리 종속성에 의존하지 않는 특정 모듈의 라이브러리가 포함됩니다. 쉽게 추가하거나 제거할 수 있습니다. 예를 들면 v7-recyclerview 및 v7-cardview가 있습니다. 기타 라이브러리: Android 지원 라이브러리는 @NonNull과 같은 주석을 지원하기 위한 RenderScript 지원을 제공하는 v8과 같은 몇 가지 다른 라이브러리로 구성됩니다.

활동의 7가지 중요한 수명 주기 메서드를 지정합니다.

  1. onCreate()
  2. 시작()
  3. onResume()
  4. onPause()
  5. 온스톱()
  6. onDestroy()
  7. onRestart()

onCreate(), onStart(), onResume(), onDestroy(), onStop(), onPause()를 구분합니다. 활동의 수명 주기 동안 언제 호출됩니까?

onCreate()는 Activity가 처음 실행될 때 호출되는 첫 번째 메서드입니다. onStart()는 onCreate()가 작업을 완료한 후에 호출됩니다. onResume()은 onStart()가 완료된 후에 호출됩니다. 활동이 전경을 벗어나면(아마도 대기/절전과 같은 더 짧은 기간 동안) onPause()가 호출된 다음 onStop()이 호출됩니다(활동이 보이지 않을 때. 예: 일부 다른 애플리케이션이 시작됨). onDestroy()는 활동 또는 애플리케이션이 종료될 때 호출됩니다. 기본적으로 수명 주기 메서드는 기간의 세 계층으로 나뉩니다.

  1. onCreate() 및 onDestroy()는 전체 활동 기간 동안 존재합니다.
  2. 활동이 표시되는 동안 onStart() 및 onStop()이 존재합니다.
  3. onResume() 및 onPause()는 활동이 전경에 있는 동안 나타납니다.

애플리케이션에서 홈 버튼을 누르면 onPause() 및 onStop()이 호출됩니다. onPause()만 호출되는 시나리오를 설명하십시오.

현재 활동을 부분적으로 가리는 새 활동을 만들고 시작합니다. 화면을 부분적으로 덮도록 layout_width 및 layout_height를 정의하면 됩니다. 이렇게 하면 첫 번째 활동이 계속 표시되지만 전경에는 표시되지 않습니다. 예: layout_width 및 layout_height를 각각 200dp로 정의합니다.

사용자가 화면을 회전할 때 활동이 어떻게 반응합니까?

화면이 회전하면 활동의 현재 인스턴스가 소멸되고 활동의 새 인스턴스가 새 방향으로 생성됩니다. onRestart() 메서드는 화면이 회전할 때 가장 먼저 호출됩니다. 다른 수명 주기 메서드는 활동이 처음 생성되었을 때와 유사한 흐름에서 호출됩니다.

다음은 activity_main.xml의 샘플 레이아웃입니다.

<?xml version="1.0" encoding="utf-8"?>	 	 
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"	 	 
 android:layout_width="match_parent"	 	 
 android:layout_height="match_parent"	 	 
 android:paddingBottom="@dimen/activity_vertical_margin"	 	 
 android:paddingLeft="@dimen/activity_horizontal_margin"	 	 
 android:paddingRight="@dimen/activity_horizontal_margin"	 	 
 android:paddingTop="@dimen/activity_vertical_margin"	 	 
 >
 	 
 <TextView	 	 
 android:layout_width="wrap_content"	 	 
 android:layout_height="wrap_content"	 	 
 android:text="0"	 	 
 android:id="@+id/textView"	 	 
 android:layout_alignParentRight="true"	 	 
 android:layout_alignParentEnd="true"	 	 
 android:layout_alignParentLeft="true"	 	 
 android:layout_alignParentStart="true" />
 	 	 
 <Button 
 android:layout_width="wrap_content"	 	 
 android:layout_height="wrap_content"	 	 
 android:text="Increment"	 	 
 android:id="@+id/button"	 	 
 android:layout_centerVertical="true"	 	 
 android:layout_centerHorizontal="true" />	 	 
</RelativeLayout>

다음은 샘플 MainActivity.java 클래스입니다.

 
public class MainActivity extends AppCompatActivity {
    Button increment;
    TextView textView;
    int i=0;

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

        increment=(Button)findViewById(R.id.button);
        textView=(TextView)findViewById(R.id.textView);

        increment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                i++;
                textView.setText(i);
            }
        });
        
    }
    
}

위의 응용 프로그램은 버튼을 클릭할 때마다 textview 값을 1씩 증가시키도록 설계되었지만 충돌이 발생합니다. 왜?

응용 프로그램은 textview가 문자열 값을 예상하기 때문에 android.content.res.Resources$NotFoundException: String resource ID #0x1 예외와 함께 충돌합니다. 위의 코드는 정수를 직접 전달합니다. 문자열로 변환해야 합니다. 이는 다음 두 가지 방법 중 하나로 수행할 수 있습니다.

  1. textView.setText(+i);
  2. textView.setText(String.valueOf(i));

위 사례에 대한 후속 질문입니다. 위의 애플리케이션은 화면 방향이 변경될 때 어떻게 반응합니까?

On-screen rotation the activity restarts and the objects are initialized again. Hence the textView counter resets to zero every time the orientation is changed.

화면이 회전할 때 데이터가 다시 로드되고 재설정되지 않도록 하려면 어떻게 해야 합니까?

The most basic approach is to add an element attribute tag `android:configChanges` inside the activity tag in the AndroidManifest.xml as shown below.

```
<activity android:name=".MainActivity"
	 android:configChanges="orientation|screenSize">
	
	<intent-filter>
	  	 <action android:name="android.intent.action.MAIN" />
	  	 <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    
</activity>            
```

In general, the configChanges for any activity are defined as

```
android:configChanges="orientation|screenSize|keyboardHidden"
```

The `keyboardHidden` configuration is to prevent the keyboard from resetting if it's pulled out.

  1. activity_main.xml의 예시 레이아웃은 다음과 같습니다. MainActivity.java에는 빈 onCreate() 메서드만 포함되어 있습니다.

```
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:paddingBottom="@dimen/activity_vertical_margin"
 	android:paddingLeft="@dimen/activity_horizontal_margin"
 	android:paddingRight="@dimen/activity_horizontal_margin"
 	android:paddingTop="@dimen/activity_vertical_margin"
>
 
  <EditText
 	android:layout_width="wrap_content"
 	android:layout_height="wrap_content"
 	android:text="Hello World!"
 	android:layout_alignParentRight="true"
 	android:layout_alignParentEnd="true"
 	android:layout_alignParentLeft="true"
 	android:layout_alignParentStart="true" />

</RelativeLayout>
```

The configChanges are defined in the AndroidManifest.xml as `android:configChanges="orientation|screenSize|keyboardHidden"`

#### Does the input text entered in the EditText persist when the orientation is changed? Yes/No? Explain.

No. Despite the configChanges defined in the AndroidManifest.xml, the EditText input text entered resets when the orientation is changed. This is because no resource id has been defined. On orientation change, the instance of the EditText gets lost. To fix this issue to work correctly add an `android:id` attribute element in the EditText tag.

android:configChanges가 권장되지 않는 이유는 무엇인가요? 방향 변경을 처리하는 더 좋은 방법이 있습니까?

`android:configChanges` is not the recommended way by Google. Though it's the simplest way to use, it comes with its own share of drawbacks. First, the common perception that android:configChanges = "orientation" will magically retain the data is a complete misinterpretation. The orientation changes can occur from a number of other events such as changing the default language can trigger a configuration change and destroy and recreate the activity. Second, the activity can restart itself if it's in the background and Android decides to free up its heap memory by killing it. When the application returns to the foreground it'll restart it's data to the original state and the user may not like that. A better alternative of `android:configChanges` is; Saving the current state of the activity when it's being destroyed and restoring the valuable data when it's restarted can be done by overriding the methods `onSaveInstanceState()` and `onRestoreInstanceState()` of the activity class.

활동 수명 주기에서 onSaveInstanceState() 및 onRestoreInstanceState()는 어디에 있습니까? 이러한 방법으로 데이터를 저장하고 복원하는 방법은 무엇입니까?

In general the onSaveInstanceState() is invoked after onPause() and before the onStop(). But the API documentation explicitly states that the onSaveInstanceState( ) method will be called before onStop() but makes no guarantees it will be called before or after onPause(). The onRestoreInstanceState() is called after onStart() is invoked. The onRestoreInstanceState() method is invoked only when the activity was killed before. If the activity is NOT killed the onSaveInstanceState() is NOT called. When the activity is being destroyed, the onSaveInstanceState() gets invoked. The onSaveInstanceState contains a Bundle parameter. The data to be saved is stored in the bundle object in the form of a HashMap. The bundle object is like a custom HashMap object. The data is retrieved in the onRestoreInstanceState() method using the keys.

EditText 필드가 포함된 레이아웃이 주어졌습니다. onSaveInstanceState() 및 onRestoreInstanceState()를 구현하여 매니페스트 파일에 android:configChanges 속성을 선언하지 않고 화면이 회전할 때 현재 입력 텍스트를 저장하고 복원합니다. MainActivity.java는 아래와 같습니다.

```
 
public class MainActivity extends AppCompatActivity {
    EditText editText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.editText);
    }
}
```

```
 
public class MainActivity extends AppCompatActivity {
    EditText editText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText = (EditText) findViewById(R.id.editText);
    }
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("myData", editText.getText().toString());
    }
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        editText.setText(savedInstanceState.getString("myData"));
    }
}
```

화면 방향을 고정하는 방법은 무엇입니까? 또한 특정 활동에 대해 화면이 항상 켜져 있도록 메커니즘을 구현하십시오.

The screen orientation can be fixed by adding the attribute `android:screenOrientation="portrait"` or `android:screenOrientation="landscape"` in the activity tag. To keep the screen always on for a particular screen add the `android:keepScreenOn="true"` in the root tag of the activity layout.

프로그래밍 방식으로 활동을 다시 시작하는 방법은 무엇입니까? 버튼 클릭으로 Activity를 다시 시작하는 restartActivity() 메서드를 구현합니다.

Given below is the MainActivity.java class

```
 
public class MainActivity extends AppCompatActivity {
    Button btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        btn = (Button) findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                restartActivity();

            }
        });
    }

    public void restartActivity() {
        //Complete the code
    }

}
```

We need to invoke the recreate method on the Activity instance as shown below.

```
public void restartActivity() {
        MainActivity.this.recreate();
    }
```

인텐트의 세 가지 일반적인 사용법과 이를 호출하는 방법을 설명합니다.

Android Intents are used to
1.  start an activity - startActivity(intent)
2.  start a service - startService(intent)
3.  deliver a broadcast - sendBroadcast(intent)

인텐트를 사용하여 전화번호를 호출하고 URL을 여는 두 가지 작업을 구현합니다.

To enable calling from the application we need to add the following permission in the manifest tag of AndroidManifest.xml

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

In the MainActivity the following code invokes an action call to the given number represented as a string. The string is parsed as a URI.

```

String phone_number = "XXXXXXX" // replace it with the number

Intent intent=new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+phone number);
startActivity(intent);
```

To open a URL we need to add the following permission.

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

The intent to view a URL is defined below.

```
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.journaldev.com/"));
startActivity(intent);
```

Intent 객체에서 setFlags()와 addFlags()의 차이점은 무엇입니까?

When we're using setFlags, we're replacing the old flags with a new set of Flags. When we use addFlags, we're appending more flags.

의도를 사용하여 새 활동을 호출할 때 활동의 백 스택을 지우는 두 가지 방법을 언급하십시오.

The first approach is to use a `FLAG_ACTIVITY_CLEAR_TOP` flag.

```
Intent intent= new Intent(ActivityA.this, ActivityB.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
```

The second way is by using `FLAG_ACTIVITY_CLEAR_TASK` and `FLAG_ACTIVITY_NEW_TASK` in conjunction.

```
Intent intent= new Intent(ActivityA.this, ActivityB.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
```

FLAG_ACTIVITY_CLEAR_TASK와 FLAG_ACTIVITY_CLEAR_TOP의 차이점은 무엇인가요?

`FLAG_ACTIVITY_CLEAR_TASK` is used to clear all the activities from the task including any existing instances of the class invoked. The Activity launched by intent becomes the new root of the otherwise empty task list. This flag has to be used in conjunction with `FLAG_ ACTIVITY_NEW_TASK`. `FLAG_ACTIVITY_CLEAR_TOP` on the other hand, if set and if an old instance of this Activity exists in the task list then barring that all the other activities are removed and that old activity becomes the root of the task list. Else if there's no instance of that activity then a new instance of it is made the root of the task list. Using `FLAG_ACTIVITY_NEW_TASK` in conjunction is a good practice, though not necessary.

FLAG_ACTIVITY_NEW_TASK가 필요한 사용 예를 하나 제시하십시오. 또한 활동이 이 플래그에 어떻게 응답하는지 설명합니다.

When we're trying to launch an activity from outside the activity's context, a FLAG\_ACTIVITY\_NEW\_TASK is compulsory else a runtime exception would be thrown. Example scenarios are: launching from a service, invoking an activity from a notification click. If the activity instance is already on the task list when the flag is set, it will invoke the onNewIntent() method of that Activity. All the implementation stuff goes in that method.

Activity의 launchMode 유형을 정의하고 각각에 대해 설명합니다.

The `android:launchMode` of an Activity can be of the following types:
-   **standard** : It's the default launch mode for an activity wherein every new instance of the activity called will be put on top of the stack as a separate entity. Hence calling startActivity() for a particular class 10 times will create 10 activities in the task list.
-   **singleTop**: It differs from the standard launch mode in the fact that when the Activity instance that's invoked is already present on the top of the stack, instead of creating a new Activity, that instance will be called. In cases where the same Activity instance is not on the top of the stack or if it doesn't exist in the stack at all then a new instance of the activity will be added to the stack. Hence we need to handle the upcoming intent in both the `onCreate()` and `onNewIntent()` methods to cover all cases.
-   **singleTask**: This is different from singleTop in the case that if the Activity instance is present in the stack, the onNewIntent() would be invoked and that instance would be moved to the top of the stack. All the activities placed above the singleTask instance would be destroyed in this case. When the activity instance does not exist in the stack, the new instance would be placed on the top of the stack similar to the standard mode.
-   **singleInstance** : An activity with this launchMode defined would place only a singleton activity instance in the Task. The other activities of the application will be placed in a separate Task.

taskAffinity란 무엇인가요?

A taskAffinity is an attribute tag defined in the activity tag in the AndroidManifest.xml for launchMode singleInstance. Activities with similar taskAffinity values are grouped together in one task. 26) You've been given an EditText that already has some text in it. How would you place the cursor at the end of the text? The current situation and the output needed are given below. [![android interview questions, taskAffinity](https://journaldev.nyc3.digitaloceanspaces.com/2016/06/edit-text-cursor-position-issue.png)](https://journaldev.nyc3.digitaloceanspaces.com/2016/06/edit-text-cursor-position-issue.png) [![android interview questions, taskAffinity](https://journaldev.nyc3.digitaloceanspaces.com/2016/06/edit-text-cursor-position-output.png)](https://journaldev.nyc3.digitaloceanspaces.com/2016/06/edit-text-cursor-position-output.png) Call the `setSelection(position)` on the EditText object with the position we need to place the cursor on. The current position is 0. To place it at the end of the current text we'll add the following code snippet in our MainActivity.

```
EditText in;

in=(EditText)findViewById(R.id.editText);
        if (in != null) {
            in.setSelection(Integer.parseInt(String.valueOf(in.getText().toString().length())));
        }
```

The setSelection method requires an integer parameter. So we're wrapping the length of the string as an Integer using parseInt.

Enter 키를 누르면 자동으로 지워지는 EditText를 구현합니다. 아래 이미지는 요구 사항을 보여줍니다.

[![edit text, textwatcher](https://journaldev.nyc3.digitaloceanspaces.com/2016/06/edit-text-textwatcher.gif)](https://journaldev.nyc3.digitaloceanspaces.com/2016/06/edit-text-textwatcher.gif) We'll add the TextWatcher class to the editText object. And check for the "\\n" character and clear the editText as shown below.

```
EditText in;
in=(EditText)findViewById(R.id.editText);

        in.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String string = s.toString();
                if (string.length() > 0 && string.charAt(string.length() - 1) == '\n') {
                    Toast.makeText(getApplicationContext(),"ENTER KEY IS PRESSED",Toast.LENGTH_SHORT).show();
                    in.setText("");
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

```

LinearLayout, RelativeLayout, AbsoluteLayout을 구분합니다.

A LinearLayout arranges its children in a single row or single column one after the other. A RelativeLayout arranges it's children in positions relative to each other or relative to parent depending upon the LayoutParams defined for each view. AbsoluteLayout needs the exact positions of the x and y coordinates of the view to position it. Though this is deprecated now.

FrameLayout과 TableLayout의 차이점은 무엇입니까?

A FrameLayout stack up child views above each other with the last view added on the top. Though we can control the position of the children inside the FrameLayout using the layout\_gravity attribute. When the width and height of the FrameLayout are set to wrap\_content, the size of the FrameLayout equals the size of the largest child (plus padding). A TableLayout consists of TableRows. The children are arranged in the form of rows and columns.

공유 기본 설정에 데이터가 어떻게 저장됩니까? commit()과 apply()의 차이점은 무엇입니까? 어떤게 추천인가요?

Data is stored in SharedPreferences in the form of a key-value pair(HashMap). commit() was introduced in API 1 whereas apply() came up with API 9. commit() writes the data synchronously and returns a boolean value of success or failure depending on the result immediately. apply() is asynchronous and it won't return any boolean response. Also, if there is an apply() outstanding and we perform another commit(), then the commit() will be blocked until the apply() is not completed. commit() is instantaneous and performs disk writes. If we're on the main UI thread apply() should be used since it's asynchronous.

사용자가 화면에서 뒤로 버튼을 누르면 어떤 메서드가 호출됩니까?

The onBackPressed() method of the Activity is invoked. Unless overridden it removes the current activity from the stack and goes to the previous activity.

onBackPressed()를 어떻게 비활성화합니까?

The onBackPressed() method is defined as shown below:

```
    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }
```

To disable the back button and preventing it from destroying the current activity and going back we have to remove the line `super.onBackPressed();`

StateListDrawable이란 무엇입니까?

A StateListDrawable is a drawable object defined in the XML that allows us to show a different color/background for a view for different states. Essentially it's used for Buttons to show a different look for each state(pressed, focused, selected, none).

눌린 상태와 누르지 않은 상태에 대해 StateListDrawable을 사용하는 버튼을 구현하고 버튼 주변의 테두리와 곡선 모서리를 사용합니다.

The selector drawable for a button is shown below.

```
<selector xmlns:android="https://schemas.android.com/apk/res/android">

<item android:state_pressed="false">
 	<shape android:shape="rectangle">
 		<solid android:color="@android:color/holo_red_dark"/>
 		<stroke android:color="#000000" android:width="3dp"/>
 		<corners android:radius="2dp"/>
	</shape>
</item>

<item android:state_pressed="true">
	<shape android:shape="rectangle">
 	 	 <solid android:color="@android:color/darker_gray"/>
 	 	 <stroke android:color="#FFFF" android:width="1dp"/>
 	 	 <corners android:radius="2dp"/>
 	</shape>
</item>

</selector>
```

We need to add this drawable XML in the android:background attribute of the button as:

```
android:background="@drawable/btn_background"
```

The output looks like this: [![android button state list, android interview questions](https://journaldev.nyc3.digitaloceanspaces.com/2016/06/button-state-list.gif)](https://journaldev.nyc3.digitaloceanspaces.com/2016/06/button-state-list.gif)

조각이란 무엇입니까? 수명주기 방법을 설명하십시오.

Fragments are a part of an activity and they contribute there own UI to the activity they are embedded in. A single activity can contain multiple fragments. Fragments are reusable across activities. The lifecycle methods of a Fragment are :

1.  `onAttach(Activity)` : is called only once when it is attached with activity.
2.  `onCreate(Bundle)` : it is used to initialise the fragment.
3.  `onCreateView(LayoutInflater, ViewGroup, Bundle)` : creates and returns view hierarchy.
4.  `onActivityCreated(Bundle)` : it is invoked after the completion of onCreate() method.
5.  `onViewStateRestored(Bundle)` : it provides information to the fragment that all the saved state of fragment view hierarchy has been restored.
6.  `onStart()` : makes the fragment visible.
7.  `onResume()` : makes the fragment interactive.
8.  `onPause()` : is called when fragment is no longer interactive.
9.  `onStop()` : is called when fragment is no longer visible
10.  `onDestroyView()` : it allows the fragment to clean up resources
11.  `onDestroy()` : it allows the fragment to do final clean up of fragment state
12.  `onDetach()` : it is called when the fragment is no longer associated with the activity

An image depicting the Fragments lifecycle is given below. [![android fragment lifecycle](https://journaldev.nyc3.digitaloceanspaces.com/2016/07/fragment-lifecycle.png)](https://journaldev.nyc3.digitaloceanspaces.com/2016/07/fragment-lifecycle.png)

버튼 클릭시 프로그래밍 방식으로 다른 활동에서 실행중인 활동을 종료하는 방법은 무엇입니까?

We'll declare and assign a class instance of the FirstActivity to itself as shown below.

```
public class FirstActivity extends AppCompatActivity {
public static FirstActivity firstActivity;

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

        firstActivity=this;
}
}
```

We'll call finish() on the above instance of the FirstActivity to kill the activity from any other activity.

```
FirstActivity.firstActivity.finish()
```

PendingIntent란 무엇입니까?

A PendingIntent is a wrapper for the Intent object. It's passed to a foreign application (NotificationManager, AlarmManager) such that when some given conditions are met, the desired action is performed on the intent object it holds onto. The foreign application performs the intent with the set of permissions defined in our application.

AsyncTask와 Thread 클래스의 차이점은 무엇입니까?

A Thread is generally used for long tasks to be run in the background. We need a Handler class to use a Thread. An AsyncTask is an intelligent Thread subclass. It's recommended to use AsyncTask when the caller class is the UI Thread as there is no need to manipulate the handlers. AsyncTask is generally used for small tasks that can communicate back with the main UI thread using the two methods onPreExecute() and onPostExecute() it has. A Handler class is preferred when we need to perform a background task repeatedly after every x seconds/minutes.

아래는 AsyncTask 예제입니다.

private class MyTask extends AsyncTask {
      protected String doInBackground(String... params) {

        Toast.makeText(getApplicationContext(),"Will this work?",Toast.LENGTH_LONG).show();

          int count = 100;
          int total = 0;
          for (int i = 0; i < count/2; i++) {
              total += i;
          }
          return String.valueOf(totalSize);
      }

      protected void onPostExecute(String result) {
       
      }
 }

위의 AsyncTask는 메인 스레드에서 어떻게 시작됩니까? 성공적으로 실행될까요?

We need to call the AsyncTask from the onCreate() using the following piece of code;

```
MyTask myTask= new MyTask();
myTask.execute();
```

No. The application will crash with a runtime exception since we're updating the UI Thread by trying to display a Toast message inside the doInBackground method. We need to get rid of that line to run the application successfully.

doInBackground 메서드의 반환 값은 어디로 갑니까? onCreate() 메서드에서 반환된 값을 어떻게 얻습니까?

The returned value of the doInBackground goes to the onPostExecute() method. We can update the main UI thread from here. To get the returned value in the onCreate() method we need to use the following code snippet.

```
MyTask myTask= new MyTask();
String result=myTask.execute().get();
```

This approach is not recommended as it blocks the main UI thread until the value is not returned. The ideal scenario to use it is when the other views of the UI thread need the value from the AsyncTask for processing.

주어진 간격 후에 반복되는 AsyncTask 구현

We need to use a Handler class in the onPostExecute that executes the AsyncTask recursively.

```
private class MyTask extends AsyncTask {
      protected String doInBackground(String... params) {

        Toast.makeText(getApplicationContext(),"Will this work?",Toast.LENGTH_LONG).show();

          int count = 100;
          int total = 0;
          for (int i = 0; i < count/2; i++) {
              total += i;
          }
          return String.valueOf(totalSize);
      }

      protected void onPostExecute(String result) {

// repeats after every 5 seconds here.
new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            new MyAsyncTask().execute("my String");
        }
    }, 5*1000);       

      }
 }
```

서비스란 무엇입니까?

A service is a component in android that's used for performing tasks in the background such as playing Music, location updating etc. Unlike activities, a service does not have a UI. Also, a service can keep running in the background even if the activity is destroyed.

서비스를 시작/중지하는 방법은 무엇입니까?

A service is started from an activity by executing the following code snippet.

```
startService(new Intent(this, MyService.class));
```

Though just executing the above code won't start a service. We need to register the service first in the AndroidManifest.xml file as shown below.

```
<service android:name="MyService"/>
```

To stop a service we execute `stopService()`. To stop the service from itself we call `stopSelf()`.

두 가지 유형의 서비스를 정의하고 구분합니다.

Services are largely divided into two categories : **Bound Services** and **Unbound/Started Services**
1.  **Bound Services**: An Android component may bind itself to a Service using `bindservice()`. A bound service would run as long as the other application components are bound to it. As soon as the components call `unbindService()`, the service destroys itself.
2.  **Unbound Services**: A service is started when a component (like activity) calls startService() method and it runs in the background indefinitely even if the original component is destroyed.

서비스의 수명 주기 방법을 설명합니다.

-   `onStartCommand()` : This method is called when startService() is invoked. Once this method executes, the service is started and can run in the background indefinitely. This method is not needed if the service is defined as a bounded service. The service will run indefinitely in the background when this method is defined. We'll have a stop the service ourselves
-   `onBind()` This method needs to be overridden when the service is defined as a bounded service. This method gets called when bindService() is invoked. In this method, we must provide an interface that clients use to communicate with the service, by returning an IBinder. We should always implement this method, but if you don’t want to allow binding, then you should return null
-   `onCreate()` : This method is called while the service is first created. Here all the service initialization is done
-   `onDestroy()` : The system calls this method when the service is no longer used and is being destroyed. All the resources, receivers, listeners clean up are done here

[![android interview questions, android service lifecycle](https://journaldev.nyc3.digitaloceanspaces.com/2016/07/service-lifecycle.png)](https://journaldev.nyc3.digitaloceanspaces.com/2016/07/service-lifecycle.png)

브로드캐스트 수신기와 서비스를 구분합니다.

A service is used for long running tasks in the background such as playing a music or tracking and updating the user's background location. A Broadcast Receiver is a component that once registered within an application executes the onReceive() method when some system event gets triggered. The events the receiver listens to are defined in the AndroidManifest.xml in the intent filters. Types of system events that a Broadcast Receiver listens to are: changes in the network, boot completed, battery low, push notifications received etc. We can even send our own custom broadcasts using `sendBroadcast(intent)`.

Broadcast Receiver는 manifest.xml에 어떻게 등록되나요?

The Broadcast Receiver is defined inside the receiver tags with the necessary actions defined inside the intent filter as shown below.

```
<receiver android:name=".ConnectionReceiver" >
	<intent-filter>
		<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
	</intent-filter>
</receiver>
```

RecyclerView는 ListView와 어떻게 다른가요?

-   A RecyclerView recycles and reuses cells when scrolling. This is a default behaviour. It's possible to implement the same in a ListView too but we need to implement a ViewHolder there
-   A RecyclerView decouples list from its container so we can put list items easily at run time in the different containers (linearLayout, gridLayout) by setting LayoutManager
-   Animations of RecyclerView items are decoupled and delegated to `ItemAnimator`

모든 헤더 그룹이 기본적으로 확장되는 ExpandableListView를 구현합니다.

We need to call the method expandGroup on the adapter to keep all the group headers as expanded.

```
ExpandableListView el = (ExpandableListView) findViewById(R.id.el_main);
elv.setAdapter(adapter);
for(int i=0; i < adapter.getGroupCount(); i++)
    el.expandGroup(i);
```

AsyncTask를 실행하는 활동이 방향을 변경하면 AsyncTask는 어떻게 됩니까?

The lifecycle of an AsyncTask is not tied onto the Activity since it's occurring on a background thread. Hence an orientation change won't stop the AsyncTask. But if the AsyncTask tries to update the UI thread after the orientation is changed, it would give rise to `java.lang.IllegalArgumentException: View not attached to window manager` since it will try to update the former instances of the activity that got reset.

/assets 및 /res/raw/ 폴더의 용도는 무엇입니까?

**/assets** folder is empty by default. We can place files such as custom fonts, game data here. Also, this folder is ideal for maintaining a custom dictionary for lookup. The original file name is preserved. These files are accessible using the AssetManager (**getAssets()**). **/res/raw** folder is used to store xml files, and files like \*.mp3, \*.ogg etc. This folder gets built using aapt and the files are accessible using R.raw.

안드로이드 인터뷰 질문과 답변은 여기까지입니다. 더 많은 Android 인터뷰 질문이 있으면 나중에 자세한 답변과 함께 목록에 추가하겠습니다.