반응형

Fragment 의 life cycle



fragment


  1. activity 를 만들기 시작
  2. fragment inflate 하고
  3. fragment 를 activity 에 attach 하고
  4. fragment 를 만들기 시작
  5. fragment 가 가지고 있는 view 를 만들기 시작
  6. view state 복원




----



  1. activity 가 create 하기 시작하면서(Activity.onCreate())
  2. activity 안의 fragment 를 inflate 한다.(Fragment.onInflate())
  3. 이 inflate 한 녀석이 activity 에 붙여지고 나서,(Fragment.onAttach())
  4. 부모가 없는 Fragment(최상위 fragment ?) 가 Activity 에 attach 됐다고 알린다.(Activity.onAttachFragment())
  5. fragment 가 create 가 시작되고,(Fragment.onCreate())
  6. fragment 안의 view 를 만들기 시작한다.(Fragment.onCreateView())
  7. 이 과정이 끝나면 activity 의 create 가 끝난것이다.(Fragment.onActivityCreate())
  8. 그리고 나면, 이제 View 가 가지고 있던 State 를 복원하기 시작한다.(Fragment.onViewStateRestored())





  1. Activity.onCreate()
    • handleLaunchActivity() > performLaunchActivity() > callActivityOnCreate() > performCreate() > onCreate()
  2. Fragment.onInflate()
    • Activity.onCreate() > setContentView > inflate() > onCreateView()  > onInflate()
  3. Fragment.onAttach()
    • Activity.onCreate() > setContentView > inflate() > onCreateView() > addFragment() > moveToState() > Fragment.INITIALIZING > onAttach()
  4. Activity onAttachFragment()
    • Activity.onCreate() > setContentView > inflate() > onCreateView() > onCreateView() > addFragment() > moveToState() > Fragment.INITIALIZING > onAttachFragment()
  5. Fragment.onCreate()
    • onCreate() > setContentView > inflate() > onCreateView() > addFragment() > moveToState() > Fragment.INITIALIZING > performCreate() > onCreate()
  6. Fragment.onCreateView()
    • onCreate() > setContentView > inflate() > onCreateView()  > addFragment() > moveToState() > Fragment.INITIALIZING > performCreateView() > onCreateView()
  7. Fragment.onActivityCreated()
    • handleLaunchActivity() > performLaunchActivity() > callActivityOnCreate() > performCreate() > dispatchActivityCreated() > moveToState() > Fragment.CREATED > performActivityCreated() > onActivityCreated()
  8. Fragment.onViewStateRestored()
    • handleLaunchActivity() > performLaunchActivity() > callActivityOnCreate() > performCreate() > dispatchActivityCreated() > moveToState() > Fragment.CREATED > restoreViewState > onViewStateRestored()






    Activity Life cycle


    from : Androidify workshop



    See Also

    1. http://stackoverflow.com/questions/14021600/fragment-viewstate-restored-in-onstart


    반응형
    ,
    반응형

    스프링에서 rest api call 하기 / spring 에서 rest call / spring 에서 http request



    RestTemplate

    Spring framework 에서 Rest API 호출을 위해 RestTemplate 이라는 것을 제공한다. ref. 2, ref. 3 에서 간단한 예제를 확인할 수 있다.


    postForObject

    Server 에서 RESTful API server 에 request 를 POST 방식으로 form 의 data 는 json 형식으로 보낼 때 방법. ElasticSearch 등을 사용할 때 활용할 수 있다. 혹시나 해서 적어놓는데, ElasticSearch 는 Java API 를 따로 제공한다.(참고)

    @Override
    public JsonResult retrieve() {
    
        String JSONInput = ("{\n" +
                "    \"aggs\": {\n" +
                "       \"aggs_stats\" : {\n" +
                "           \"date_histogram\":{\n" +
                "             \"field\" : \"event_timestamp\",\n" +
                "             \"interval\" : \"hour\"\n" +
                "           }\n" +
                "       }\n" +
                "    }\n" +
                "} ");
    
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity param= new HttpEntity(JSONInput, headers);
    
    
        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.postForObject(url, param, String.class);
    
        return new ElasticSearchResult(result);
    
    }



    setMessageConverters

    ref. 5ref. 6 을 통해서 MessageConverters 를 설정해서 postForObject 를 이용하는 방법을 알아볼 수 있다.


    // RestTemplate 에 MessageConverter 세팅
    List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
    converters.add(new FormHttpMessageConverter());
    converters.add(new StringHttpMessageConverter());
    
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setMessageConverters(converters);
    
    // parameter 세팅
    MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
    map.add("name", "xx");
    map.add("password", "xx");
    
    // post
    String result = rest.postForObject("http://localhost:8080/soa-server/user/", map, String.class);
    System.out.println(result);
    



    getForObject 의 한계

    Accept 를 따로 정해주지 않는 경우에 RestTemplate#getForObject 에서는 기본적으로 아래 header 를 이용한다.
    Accept : application/json, application/*+json

    그래서 getForObject 를 이용해서 만약에 다른 Accept 를 사용하고 싶다면, 다른 함수를 이용해야 한다.(execute, exchange)

    getForObject 에서 param 을 주는 방법

    ref. 4 를 참고하자. 대략 아래와 같은 방식을 이용한다.

    UriComponentsBuilder urlWithoutParam 
        = UriComponentsBuilder.fromUriString("http://dd.net")
                    .path("/path1/ddd");
            
    for(Map.Entry<String, Object> e: param.entrySet()){
        urlWithoutParam = urlWithoutParam.queryParam(e.getKey(), e.getValue());
    }
    URI reqUrl = urlWithoutParam.build().toUri();
    
    
    RestTemplate restTemplate = new RestTemplate();
    return restTemplate.getForObject(reqUrl, String.class);




    RestTemplate#execute

    좀 더 자유로운 Http request 를 위해서 execute 를 사용하게 되었다. 그리고 이 RestTemplate 의 doExecute 에서 Extractor 를 사용하기 때문에 이 녀석만 제대로 맞춰 주면 된다.

    protected <T> T doExecute(URI url, HttpMethod method, 
                            RequestCallback requestCallback,
                            ResponseExtractor<T> responseExtractor) 
                            throws RestClientException {
        try {
            ClientHttpRequest request = createRequest(url, method);
            if (requestCallback != null) {
                requestCallback.doWithRequest(request);
            }
            response = request.execute();
            if (!getErrorHandler().hasError(response)) {
                logResponseStatus(method, url, response);
            }
            else {
                handleResponseError(method, url, response);
            }
            if (responseExtractor != null) {
                return responseExtractor.extractData(response);
            }
    



    Example


    // ApiCallResponseExtractor.java
    public class ApiCallResponseExtractor extends HttpMessageConverterExtractor<String> {
    
        public ApiCallResponseExtractor (Class<String> responseType,
                                    List<HttpMessageConverter<?>> messageConverters) {
            super(responseType, messageConverters);
        }
    
        @Override
        public String extractData(ClientHttpResponse response) throws IOException {
    
            String result;
    
            if (response.getStatusCode() == HttpStatus.OK) {
                Scanner scanner = new java.util.Scanner(response.getBody()).useDelimiter("[\\(\\)]");
                scanner.next(); // callback name,
                String json = scanner.next();
                result = json;
    
            } else {
                result = null;
            }
    
            return result;
        }
    }


    // MyController.java
    final String url = "http://10.10.2.100:8080/portal/customer/getCustomerList?" +
                    JsonKey.CALLBACK + "={" + JsonKey.CALLBACK + "}" + "&" +
                    JsonKey.USER_ID + "={" + JsonKey.USER_ID + "}";
    Map<String, String> vars = new HashMap<String, String>();
    vars.put(JsonKey.CALLBACK, JsonKey.API_CALLBACK_NAME);
    vars.put(JsonKey.USER_ID, "test_id");
    
    RestTemplate restTemplate = new RestTemplate();
    ResponseExtractor<String> responseExtractor =
            new ApiCallResponseExtractor(String.class, restTemplate.getMessageConverters());
    
    String response = restTemplate.execute(url, HttpMethod.GET, null, responseExtractor, vars);



    Header field Accept

    참고로 execute 를 사용하면 기본 Accept 는 아래를 사용하게 된다.

    Accept : text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2



    RestTemplate 을 이용해서 json request

    ref. 7 에 잘 나와 있다.



    Reference

    1. RestTemplate (Spring Framework 4.1.3.RELEASE API)
    2. http://spring.io/guides/gs/consuming-rest/#initial
    3. http://spring.io/blog/2009/03/27/rest-in-spring-3-resttemplate
    4. android - How to send a getForObject request with parameters Spring MVC - Stack Overflow
    5. java - Spring RestTemplate postForObject with Header: webservice can't find my header parameters - Stack Overflow
    6. Sending POST parameters with RestTemplate requests - Spring Forum
    7. Rest Template Json Request | Spring Tutorials


    반응형
    ,
    반응형

    자바에서 HttpURLConnection은 대단히 자주 사용하는 클래스라고 할 수 있다!

    다음은 가장 기본이 되는 호출 예제이다!<rest의 시대(?)를 살고 있는 개발자에게 필수가 아닐까?>



    출처: http://nine01223.tistory.com/229 [스프링연구소(spring-lab)]

    반응형
    ,
    반응형
    public abstract class AbsFragmentNew<T extends Object> extends Fragment

    이런 class를 만들 때 "T"의 데이터 타입을 알아내기 위한 방법

    Type superclass = getClass().getGenericSuperclass();
    if(superclass instanceof ParameterizedType) {
    Type[] genericTypes = ((ParameterizedType) superclass).getActualTypeArguments();
    if (genericTypes.length > 0) {
    try {
    Type genericType = genericTypes[0];
    String className = genericType.toString().split(" ")[1];
    classType = (Class<T>) Class.forName(className);
    } catch (ClassNotFoundException e) {
    Log.e(TAG, e);
    }
    }
    }


    반응형
    ,
    반응형

    input 자동완성기능 끄기

    요즘은 홈페이지를 만드시는 분들이 자체적으로 자동완성 기능을 구현하는 경우가 있습니다.

    그런데, 이런 맘을 몰라주고 브라우저에서 제시하는 자동완성 기능이 떠오르곤 하지요.

    브라우저의 환경 설정에 따라 브라우저의 자동완성기능이 비 활성화되는 경우도 있지만, 그렇지 않은 브라우저 사용자를 생각하면 이 부분을 홈페이지 소스를 수정하여 비활성화시켜야 하겠습니다.

    다행히 방법은 상당히 간단합니다.

    <input type=text id=keyword name=keyword  autocomplete=off

    이렇게 해주시면 브라우저의 자동완성기능이 비활성화됩니다.

    물론 off 를 on으로 해주면 활성화되겠지요.


    출처: http://tipsbox.tistory.com/entry/input-%EC%9E%90%EB%8F%99%EC%99%84%EC%84%B1-%EB%81%84%EA%B8%B0-HTML

    반응형

    'Tech develop > Html' 카테고리의 다른 글

    [css]이미지 센터 정사각형으로 CROP하기  (0) 2016.04.26
    ,
    반응형

    Name:







    반응형
    ,
    반응형


    CSS를 활용하여 이미지를 정사각형으로 자르기


    HTML

    <div class="thumb">
        <img src="http://lorempixel.com/400/800" alt="" />
    </div>

    CSS

    .thumb {
        display: block;
        overflow: hidden;
        height: 200px;
        width: 200px;
    }
    
    .thumb img {
        display: block; /* Otherwise it keeps some space around baseline */
        min-width: 100%;    /* Scale up to fill container width */
        min-height: 100%;   /* Scale up to fill container height */
        -ms-interpolation-mode: bicubic; /* Scaled images look a bit better in IE now */
    }

    1. Html은 <ima>를 <div>로 감싼다.

    2. Css에는 지정 할 정사각형의 크기를 <div>의 속성에 정의를 하고, 이미지에  min-width: 100%;  min-height: 100%; 를 정의하면 끝!!

    쉽죠??


    예제를 통해 알아보면




    이렇게 하면 결과는~~~~



    Image crop

    After CSS crop

    Before CSS crop


    반응형

    'Tech develop > Html' 카테고리의 다른 글

    input 자동완성 끄기 HTML  (0) 2016.04.28
    ,
    반응형

    GC는 Garbage Collector의 약자입니다


    dalvikvm Tag 로 


    GC_CONCURRENT freed 11405k, 59% free 3107K/7431K, external 3299k/4120k, puased 4ms+3ms


    라는 log가 찍힙니다. 


    다음과 같은 format으로 로그가 찍힙니다.


    [Reason] [Amount Freed], [Heap Statistics], [External Memory Statistics], [Pause Time]


    [Reason] : GC 발동의 원인을 나타냅니다.


    1. GC_FOR_MALLOC : 객체 생성의 있어서 힘에 메모리를 할달 받아야 할 때 힙에 남아있는 사용가능한 메모리 공간이 충분치 않을때.

    2. GC_EXPLICIT : GC가 명시적으로 불렸을 때. Runtime.gc(), VMRuntime.gc(), SIGUSR1 등.

    3. GC_CONCURRENT : 힙의 사용 한계점(사용 한계점은 내부적으로 정해진다.)을 넘어섰을때.

    4. GC_EXTERNAL_ALLOC : VM이 garbage 될 객체들이 사용하고 있는 공간을 그렇지 않은 객체들을 위해 공간을 미리 확보하려 할때.

    5. GC_HPROF_DUMP_HEAP : 힙의 컨텐츠를 파일로 저장할 때(WITH_HPROF flag를 사용할 때만)


    [Amount Freed] : 말 그대로 읽은 파일의 Kbyte를 나타낸다.


    [Heap Statistics] : GC가 발동 된 이후의 상태를 말한다. 


    59% free 3107K/7431K => 남은 공간 59%, 사용중인 공간 3107K, 힙의 총 사이즈 7413K


    [External Memory Statistics] : 외부 메모리 관련인데.... Bitmap 관련해서 외부메모리 따로 할당하는 것인데... 잘 이해가 안가서 생략.... ㅈㅅ (Bitmap 관련해서 따로 메모리를 쓰는 경우가 아니라면 값이 변하지 않는 것 같습니다.)


    [Pause Time] : GC로 인해 일시정지된 시간 (milliseconds)


    4ms+3ms => GC_CONCURRENT 일때에만 2개의 []ms+[]ms 꼴로 출력된다. 앞의 []ms는 GC가 발동되기 이전의 pause 시간이고, 뒤의 []ms는 garbage collecting이 거의 완료된 순간에 pause된 시간이다. 


    참고 문헌 : http://stackoverflow.com/questions/4976566/what-do-gc-for-malloc-gc-explicit-and-other-gc-mean-in-android-logcat 


    반응형
    ,
    반응형

    Imgur Shared Element Transition

    Activity Shared Elements Transitions

    Note that the shared element transitions require Android 5.0 (API level 21) and above and will be ignored for any lower API versions. Be sure to check the version at runtime before using API 21 specific features.

    1. Enable Window Content Transitions

    Enable Window Content Transitions in your styles.xml file:

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="android:windowContentTransitions">true</item>
        ...
    </style>

    2. Assign a Common Transition Name

    Assign a common transition name to the shared elements in both layouts. Use theandroid:transitionName attribute.

    For e.g. in MainActivity.xml:

    <android.support.v7.widget.CardView
      ...>
          <ImageView
              android:id="@+id/ivProfile"
              android:transitionName="profile"
              android:scaleType="centerCrop"
              android:layout_width="match_parent"
              android:layout_height="160dp" />
          ...
    </android.support.v7.widget.CardView>

    In DetailActivity.xml:

    <LinearLayout
      ...>
          <ImageView
              android:id="@+id/ivProfile"
              android:transitionName="profile"
              android:scaleType="centerCrop"
              android:layout_width="match_parent"
              android:layout_height="380dp" />
          ...
    </LinearLayout>

    Note that it doesn't matter if the android:id is different or where in the layout hierarchy the source and target views exist.

    3. Start Activity

    Start the target activity by specifying a bundle of those shared elements and views from the source.

    Intent intent = new Intent(this, DetailsActivity.class);
    // Pass data object in the bundle and populate details activity.
    intent.putExtra(DetailsActivity.EXTRA_CONTACT, contact);
    ActivityOptionsCompat options = ActivityOptionsCompat.
        makeSceneTransitionAnimation(this, (View)ivProfile, "profile");
    startActivity(intent, options.toBundle());

    Thats it! Specifying the source view along with the transition name ensures that even if you have multiple views with the same transition name in the source hierarchy, it will essentially be able to pick the right view to start the animation from.

    To reverse the scene transition animation when you finish the second activity, call theActivity.supportFinishAfterTransition() method instead of Activity.finish(). Also, you will need to override the behavior of the home button in the ToolBar/ ActionBar for such cases:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            // Respond to the action bar's Up/Home button
            case android.R.id.home:
                supportFinishAfterTransition();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    4. Multiple Shared Elements

    Sometimes, you might want to animate multiple elements from the source view hierarchy. This can be achieved by using distinct transition names in the source and target layout xml files.

    Intent intent = new Intent(context, DetailsActivity.class);
    intent.putExtra(DetailsActivity.EXTRA_CONTACT, contact);
    Pair<View, String> p1 = Pair.create((View)ivProfile, "profile");
    Pair<View, String> p2 = Pair.create(vPalette, "palette");
    Pair<View, String> p3 = Pair.create((View)tvName, "text");
    ActivityOptionsCompat options = ActivityOptionsCompat.
        makeSceneTransitionAnimation(this, p1, p2, p3);
    startActivity(intent, options.toBundle());

    Note: By default android.util.Pair will be imported but we want to select theandroid.support.v4.util.Pair class instead.

    Be careful to not overdo transitions between shared elements. While it can make sense to have one cohesive unit animate from one screen to another (which may or may not contain multiple shared elements), having too many shared elements will result in a distracting animation which makes the experience more jarring.

    5. Customizing Shared Elements Transition

    In Android L, shared elements transition defaults to a combination of ChangeBounds,ChangeTransformChangeImageTransform, and ChangeClipBounds. This works well for most typical cases. However, you may customize this behavior or even define your own custom transition.

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- enable window content transitions -->
        <item name="android:windowContentTransitions">true</item>
    
        <!-- specify enter and exit transitions -->
        <!-- options are: explode, slide, fade -->
        <item name="android:windowEnterTransition">@transition/change_image_transform</item>
        <item name="android:windowExitTransition">@transition/change_image_transform</item>
    
        <!-- specify shared element transitions -->
        <item name="android:windowSharedElementEnterTransition">
          @transition/change_image_transform</item>
        <item name="android:windowSharedElementExitTransition">
          @transition/change_image_transform</item>
    </style>

    The change_image_transform transition in this example is defined as follows:

    <!-- res/transition/change_image_transform.xml -->
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
      <changeImageTransform/>
    </transitionSet>

    To enable window content transitions at runtime instead, call the Window.requestFeature()method:

    // inside your activity (if you did not enable transitions in your theme)
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    // set an enter transition
    getWindow().setEnterTransition(new Explode());
    // set an exit transition
    getWindow().setExitTransition(new Explode());

    See this official guide on Defining Custom Animations for more details.

    Fragment Shared Elements Transitions

    Leveraging shared element transitions works with fragments too in a similar way as was shown above for activities.

    Note that the shared element transitions require Android 5.0 (API level 21) and above and will be ignored for any lower API versions. Be sure to check the version at runtime before using API 21 specific features.

    Assign a Common Transition Name

    Within two fragments let's assign a common transition name to the shared elements in both layouts. Use the android:transitionName attribute and put the view inside bothFirstFragment and SecondFragment:

    <android.support.v7.widget.CardView
      ...>
          <ImageView
              android:id="@+id/ivProfile"
              android:transitionName="profile"
              android:scaleType="centerCrop"
              android:layout_width="match_parent"
              android:layout_height="160dp" />
          ...
    </android.support.v7.widget.CardView>

    Define the Transition

    Add a transition to the res/transition folder named change_image_transform.xml with the following:

    <?xml version="1.0" encoding="utf-8"?>
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
        <changeImageTransform />
    </transitionSet>

    Animate Transition in FragmentTransaction

    Now within the activity, we can trigger the transition as part of any FragmentTransaction:

    // Get access to or create instances to each fragment
    FirstFragment fragmentOne = ...;
    SecondFragment fragmentTwo = ...;
    // Check that the device is running lollipop
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Inflate transitions to apply
        Transition changeTransform = TransitionInflater.from(this).
              inflateTransition(R.transition.change_image_transform);
        Transition explodeTransform = TransitionInflater.from(this).
              inflateTransition(android.R.transition.explode);
    
        // Setup exit transition on first fragment
        fragmentOne.setSharedElementReturnTransition(changeTransform);
        fragmentOne.setExitTransition(explodeTransform);
    
        // Setup enter transition on second fragment
        fragmentTwo.setSharedElementEnterTransition(changeTransform);
        fragmentTwo.setEnterTransition(explodeTransform);
    
        // Find the shared element (in Fragment A)
        ImageView ivProfile = (ImageView) findViewById(R.id.ivProfile);
    
        // Add second fragment by replacing first 
        FragmentTransaction ft = getFragmentManager().beginTransaction()
                .replace(R.id.container, fragmentTwo)
                .addToBackStack("transaction")
                .addSharedElement(ivProfile, "profile");
        // Apply the transaction
        ft.commit();
    }
    else {
        // Code to run on older devices
    }

    Note that we need use methods on the exiting fragment such assetSharedElementReturnTransition and setExitTransition. On the entering fragment, we call setSharedElementEnterTransition and setEnterTransition. Finally we need to find the instance of the shared element and then call addSharedElement(view, transitionName) as part of building the FragmentTransaction. Additional external resources for fragment-to-fragment shared element transitions include:

    With that you can apply these handy transitions to fragments as well as to activities.


    출처: https://github.com/codepath/android_guides/wiki/Shared-Element-Activity-Transition

    반응형
    ,
    반응형
    Log.i(TAG, "BOARD = " + Build.BOARD);
    Log.i(TAG, "BRAND = " + Build.BRAND);
    Log.i(TAG, "CPU_ABI = " + Build.CPU_ABI);
    Log.i(TAG, "DEVICE = " + Build.DEVICE);
    Log.i(TAG, "DISPLAY = " + Build.DISPLAY);
    Log.i(TAG, "FINGERPRINT = " + Build.FINGERPRINT);
    Log.i(TAG,  "HOST = " + Build.HOST);
    Log.i(TAG, "ID = " + Build.ID);
    Log.i(TAG, "MANUFACTURER = " + Build.MANUFACTURER);
    Log.i(TAG, "MODEL = " + Build.MODEL);
    Log.i(TAG, "PRODUCT = " + Build.PRODUCT);
    Log.i(TAG, "TAGS = " + Build.TAGS);
    Log.i(TAG, "TYPE = " + Build.TYPE);
    Log.i(TAG, "USER = " + Build.USER);
    Log.i(TAG, "VERSION.RELEASE = " + Build.VERSION.RELEASE);


    반응형
    ,