2012년 7월 4일 수요일

Fragments API 포스트


03 FEBRUARY 2011

The Android 3.0 Fragments API

[This post is by Dianne Hackborn, a Software Engineer who sits very near the exact center of everything Android. — Tim Bray]
An important goal for Android 3.0 is to make it easier for developers to write applications that can scale across a variety of screen sizes, beyond the facilities already available in the platform:
  • Since the beginning, Android’s UI framework has been designed around the use of layout managers, allowing UIs to be described in a way that will adjust to the space available. A common example is a ListView whose height changes depending on the size of the screen, which varies a bit between QVGA, HVGA, and WVGA aspect ratios.
  • Android 1.6 introduced a new concept of screen densities, making it easy for apps to scale between different screen resolutions when the screen is about the same physical size. Developers immediately started using this facility when higher-resolution screens were introduced, first on Droid and then on other phones.
  • Android 1.6 also made screen sizes accessible to developers, classifying them into buckets: “small” for QVGA aspect ratios, “normal” for HVGA and WVGA aspect ratios, and “large” for larger screens. Developers can use the resource system to select between different layouts based on the screen size.
The combination of layout managers and resource selection based on screen size goes a long way towards helping developers build scalable UIs for the variety of Android devices we want to enable. As a result, many existing handset applications Just Work under Honeycomb on full-size tablets, without special compatibility modes, with no changes required. However, as we move up into tablet-oriented UIs with 10-inch screens, many applications also benefit from a more radical UI adjustment than resources can easily provide by themselves.

Introducing the Fragment

Android 3.0 further helps applications adjust their interfaces with a new class called Fragment. A Fragment is a self-contained component with its own UI and lifecycle; it can be-reused in different parts of an application’s user interface depending on the desired UI flow for a particular device or screen.
In some ways you can think of a Fragment as a mini-Activity, though it can’t run independently but must be hosted within an actual Activity. In fact the introduction of the Fragment API gave us the opportunity to address many of the pain points we have seen developers hit with Activities, so in Android 3.0 the utility of Fragment extends far beyond just adjusting for different screens:
  • Embedded Activities via ActivityGroup were a nice idea, but have always been difficult to deal with since Activity is designed to be an independent self-contained component instead of closely interacting with other activities. The Fragment API is a much better solution for this, and should be considered as a replacement for embedded activities.
  • Retaining data across Activity instances could be accomplished through Activity.onRetainNonConfigurationInstance(), but this is fairly klunky and non-obvious. Fragment replaces that mechanism by allowing you to retain an entire Fragment instance just by setting a flag.
  • A specialization of Fragment called DialogFragment makes it easy to show a Dialog that is managed as part of the Activity lifecycle. This replaces Activity’s “managed dialog” APIs.
  • Another specialization of Fragment called ListFragment makes it easy to show a list of data. This is similar to the existing ListActivity (with a few more features), but should reduce the common question about how to show a list with some other data.
  • The information about all fragments currently attached to an activity is saved for you by the framework in the activity’s saved instance state and restored for you when it restarts. This can greatly reduce the amount of state save and restore code you need to write yourself.
  • The framework has built-in support for managing a back-stack of Fragment objects, making it easy to provide intra-activity Back button behavior that integrates the existing activity back stack. This state is also saved and restored for you automatically.

Getting started

To whet your appetite, here is a simple but complete example of implementing multiple UI flows using fragments. We first are going to design a landscape layout, containing a list of items on the left and details of the selected item on the right. This is the layout we want to achieve:
The code for this activity is not interesting; it just calls setContentView() with the given layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <fragment class="com.example.android.apis.app.TitlesFragment"
            android:id="@+id/titles" android:layout_weight="1"
            android:layout_width="0px"
            android:layout_height="match_parent" />

    <FrameLayout android:id="@+id/details" android:layout_weight="1"
            android:layout_width="0px"
            android:layout_height="match_parent" />
    </LinearLayout>
You can see here our first new feature: the <fragment> tag allows you to automatically instantiate and install a Fragment subclass into your view hierarchy. The fragment being implemented here derives from ListFragment, displaying and managing a list of items the user can select. The implementation below takes care of displaying the details of an item either in-place or as a separate activity, depending on the UI layout. Note how changes to fragment state (the currently shown details fragment) are retained across configuration changes for you by the framework.
public static class TitlesFragment extends ListFragment {
    boolean mDualPane;
    int mCurCheckPosition = 0;

    @Override
    public void onActivityCreated(Bundle savedState) {
        super.onActivityCreated(savedState);

        // Populate list with our static array of titles.
        setListAdapter(new ArrayAdapter<String>(getActivity(),
                R.layout.simple_list_item_checkable_1,
                Shakespeare.TITLES));

        // Check to see if we have a frame in which to embed the details
        // fragment directly in the containing UI.
        View detailsFrame = getActivity().findViewById(R.id.details);
        mDualPane = detailsFrame != null
                && detailsFrame.getVisibility() == View.VISIBLE;

        if (savedState != null) {
            // Restore last state for checked position.
            mCurCheckPosition = savedState.getInt("curChoice", 0);
        }

        if (mDualPane) {
            // In dual-pane mode, list view highlights selected item.
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            // Make sure our UI is in the correct state.
            showDetails(mCurCheckPosition);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("curChoice", mCurCheckPosition);
    }

    @Override
    public void onListItemClick(ListView l, View v, int pos, long id) {
        showDetails(pos);
    }

    /**
     * Helper function to show the details of a selected item, either by
     * displaying a fragment in-place in the current UI, or starting a
     * whole new activity in which it is displayed.
     */
    void showDetails(int index) {
        mCurCheckPosition = index;

        if (mDualPane) {
            // We can display everything in-place with fragments.
            // Have the list highlight this item and show the data.
            getListView().setItemChecked(index, true);

            // Check what fragment is shown, replace if needed.
            DetailsFragment details = (DetailsFragment)
                    getFragmentManager().findFragmentById(R.id.details);
            if (details == null || details.getShownIndex() != index) {
                // Make new fragment to show this selection.
                details = DetailsFragment.newInstance(index);

                // Execute a transaction, replacing any existing
                // fragment with this one inside the frame.
                FragmentTransaction ft
                        = getFragmentManager().beginTransaction();
                ft.replace(R.id.details, details);
                ft.setTransition(
                        FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                ft.commit();
            }

        } else {
            // Otherwise we need to launch a new activity to display
            // the dialog fragment with selected text.
            Intent intent = new Intent();
            intent.setClass(getActivity(), DetailsActivity.class);
            intent.putExtra("index", index);
            startActivity(intent);
        }
    }
}
For this first screen we need an implementation of DetailsFragment, which simply shows a TextView containing the text of the currently selected item.
public static class DetailsFragment extends Fragment {
    /**
     * Create a new instance of DetailsFragment, initialized to
     * show the text at 'index'.
     */
    public static DetailsFragment newInstance(int index) {
        DetailsFragment f = new DetailsFragment();

        // Supply index input as an argument.
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);

        return f;
    }

    public int getShownIndex() {
        return getArguments().getInt("index", 0);
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater,
            ViewGroup container, Bundle savedInstanceState) {
        if (container == null) {
            // Currently in a layout without a container, so no
            // reason to create our view.
            return null;
        }

        ScrollView scroller = new ScrollView(getActivity());
        TextView text = new TextView(getActivity());
        int padding = (int)TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                4, getActivity().getResources().getDisplayMetrics());
        text.setPadding(padding, padding, padding, padding);
        scroller.addView(text);
        text.setText(Shakespeare.DIALOGUE[getShownIndex()]);
        return scroller;
    }
}
It is now time to add another UI flow to our application. When in portrait orientation, there is not enough room to display the two fragments side-by-side, so instead we want to show only the list like this:
With the code shown so far, all we need to do here is introduce a new layout variation for portrait screens like so:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <fragment class="com.example.android.apis.app.TitlesFragment"
            android:id="@+id/titles"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
</FrameLayout>
The TitlesFragment will notice that it doesn’t have a container in which to show its details, so show only its list. When you tap on an item in the list we now need to go to a separate activity in which the details are shown.
With the DetailsFragment already implemented, the implementation of the new activity is very simple because it can reuse the same DetailsFragment from above:
public static class DetailsActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getResources().getConfiguration().orientation
                == Configuration.ORIENTATION_LANDSCAPE) {
            // If the screen is now in landscape mode, we can show the
            // dialog in-line so we don't need this activity.
            finish();
            return;
        }

        if (savedInstanceState == null) {
            // During initial setup, plug in the details fragment.
            DetailsFragment details = new DetailsFragment();
            details.setArguments(getIntent().getExtras());
            getSupportFragmentManager().beginTransaction().add(
                    android.R.id.content, details).commit();
        }
    }
}
Put that all together, and we have a complete working example of an application that fairly radically changes its UI flow based on the screen it is running on, and can even adjust it on demand as the screen configuration changes.
This illustrates just one way fragments can be used to adjust your UI. Depending on your application design, you may prefer other approaches. For example, you could put your entire application in one activity in which you change the fragment structure as its state changes; the fragment back stack can come in handy in this case.
More information on the Fragment and FragmentManager APIs can be found in the Android 3.0 SDK documentation. Also be sure to look at the ApiDemos app under the Resources tab, which has a variety of Fragment demos covering their use for alternative UI flow, dialogs, lists, populating menus, retaining across activity instances, the back stack, and more.

Fragmentation for all!

For developers starting work on tablet-oriented applications designed for Android 3.0, the new Fragment API is useful for many design situations that arise from the larger screen. Reasonable use of fragments should also make it easier to adjust the resulting application’s UI to new devices in the future as needed -- for phones, TVs, or wherever Android appears.
However, the immediate need for many developers today is probably to design applications that they can provide for existing phones while also presenting an improved user interface on tablets. With Fragment only being available in Android 3.0, their shorter-term utility is greatly diminished.
To address this, we plan to have the same fragment APIs (and the new LoaderManager as well) described here available as a static library for use with older versions of Android; we’re trying to go right back to 1.6. In fact, if you compare the code examples here to those in the Android 3.0 SDK, they are slightly different: this code is from an application using an early version of the static library fragment classes which is running, as you can see on the screenshots, on Android 2.3. Our goal is to make these APIs nearly identical, so you can start using them now and, at whatever point in the future you switch to Android 3.0 as your minimum version, move to the platform’s native implementation with few changes in your app.
We don’t have a firm date for when this library will be available, but it should be relatively soon. In the meantime, you can start developing with fragments on Android 3.0 to see how they work, and most of that effort should be transferable.

출처 : http://android-developers.blogspot.kr/2011/02/android-30-fragments-api.html

Picture Class는 무엇에 쓰는 물건?

결론은 당신의 View가 canvas를 채우기 위해 jni pass를 하는 연산이 많이 수행된다면 Picture로 한번 canvas를 감싸는것을 고려해 볼수 있다.


developer.android.com의 Picture 설명을 보면

A picture records drawing calls (via the canvas returned by beginRecording) and can then play them back (via picture.draw(canvas) or canvas.drawPicture). The picture's contents can also be written to a stream, and then later restored to a new picture (via writeToStream / createFromStream). For most content (esp. text, lines, rectangles), drawing a sequence from a picture can be faster than the equivalent API calls, since the picture performs its playback without incurring any java-call overhead.




JNI콜의 오버해드를 줄일수 있다고 나온다. 왜그럴까?



http://www.androidjavadoc.com/1.0_r1_src/android/graphics/class-use/Picture.html 를 보면 수많은 View중 굳이 WebView만이 Picture class를 이용해서 그림을 그린다. 그 이유는 WebView의 canvas에 그림을 채우기 위해 WebKit의 Render Object에 수많은 함수 콜을 해야 할 것이다. 그러면 jni의 overhead가 걸릴텐대 그래서 Picture를 쓴다.

어떻게 Picture가 jni의 overhead를 없에는지 설명해보자

우선 사용법부터 설명하면

보통은 View의 Draw를 overriding할때
Draw(canvas) {
super.onDraw(canvas);
}
일텐데 Picture를 사용하면
Draw(canvas) {
super.onDraw(mPicture.beginRecording(getWidth(), getHeight());
mPicture.endRecording();

canvas.drawPicture(mPicture);
}
라는 식으로 코딩을 하게 된다.

한마디로 Picture의 member variable canvas에 View의 child들을 순회하면서 그림을 그린뒤
Picture의 canvas를 대빵 View의 canvas가 받아서 한꺼번에 그리는 것이다.

중간에 중개자가 끼었는데 속도가 오히려 빨라진다? 가 이상하게 느껴질수 있는데.. jni의 overhead를 상쇄하므로써 속도에 이익을 얻는것이 결론이다.

Android의 모든 graphic library는 Skia library와 거이 1:1 매핑된다. 
한마디로 어떤 Class의 method를 쓰더라도  jni를 거쳐서 skia가 실행하는것이다.

Picture.beginRecording을 하면 jni밑에 C에서 SkPicture가 SkCanvas의 instance가 그림을 그릴 준비를 한다. 그 뒤 Picture.beginRecording에 그림을 그리면 java까지 올라올 필요 없이 C에서 skia로 그림을 그린다.. jni오버해드가 사라지는 지점이다. 그림을 다 그리면 java에서 Picture의 canvas를 가지고 그림을 그리는것이다.

결론

1. jni오버해드를 줄이고 싶을때  Picture를 써라
2. View의 그림을 변형해서 여러번 그리고 싶을때 Picture를 써라 (가령 거울대칭으로 그림을 그리고 싶다 등등)

2012년 7월 2일 월요일

카카오 톡

출처 : http://logfile.tistory.com/1119


곡식이 여물고 가을걷이가 시작되기까지는 많은 시간이 걸립니다. 시간뿐 아니라 수많은 노력이 더해져야 제대로 된 추수를 할수 있는 것이죠. 카카오톡이 가을걷이를 위해 한발 더 전진한 느낌입니다. 오랜 시간 많은 노력을 했고 조금만 더 노력하면 가을걷이를 시작할수 있을것도 같네요. 지난 10월 12일 카카오톡이 버전 2.5.0으로 업데이트 되었습니다. 그동안 수많은 버전업이 있었지만 이번 업데이트는 지금까지와는 다른 느낌으로 다가오는군요.


카카오 라운지

블로거 간담회가 열려 처음 방문한 카카오톡이 입주해 있는 C&K 빌딩과 간담회가 열린 카카오 라운지는 조금 색다른 분위기가 느껴졌습니다. 아쉽게도 건물에 대한 사진은 많이 찍어오지 못했네요. 카카오 라운지를 다시 방문할 기회가 주어진다면 건물의 분위기 및 특징을 다시 한번 자세히 살펴봐야 할것 같습니다. 오늘은 새롭게 업데이트된 카카오톡에 대해 조금 집중해 보도록 하겠습니다.

카카오톡 블로거 데이

카카오톡은 지난 10월 12일 버전 2.5.0으로 업데이트 되었습니다. 이번 업데이트에서 가장 눈에 띄는 점은 사진에 쓰여 있는대로 카카오톡이 플랫폼으로 진화했다는 점입니다. 단순한 메시징 앱을 벗어난 플랫폼으로의 진화, 카카오톡이 대대적인 업데이트가 시작된 것이죠. 

카카오톡

블로거 간담회가 시작되고 우선 카카오톡의 이제범 대표가 카카오톡의 성장세에 대해 브리핑을 하기 시작했습니다. 카카오톡의 이제범 대표는 카카오톡이 최근 회원수 2600만명을 넘어섰고 이같은 추세라면 올해안에 3000만명의 회원을 넘어설 것이라는 전망을 내놓았습니다.

카카오톡 사용자수

카카오톡은 서비스 초기에 많은 해외 이용자수로 관심을 많이 받았죠. 현재 해외 이용자 비율은 전체 사용자의 약 20% 정도로 약 520만명이 해외에서 카카오톡을 사용하고 있는 셈입니다. 

카카오톡 사용 국가

카카오톡은 전세계 216개국에서 사용되고 있으며 그중 사용자가 가장 많은 나라는 역시 미국으로 165만명이 카카오톡을 미국에서 사용중입니다. 

카카오톡 해외 사용자수 분포

미국은 재미동포도 많이 거주하고 있고 유학생들도 많아 카카오톡을 많이 사용한다고 쳐도 중동지역에 카카오톡 사용자가 많다는 점은 저뿐 아니라 카카오톡 역시 의아해 하는 부분입니다. 사진에서는 이제범 대표에 가려 잘 보이지 않지만 세번째로 많은 사용자가 있는 지역이 바로 중동(Middle East)지역입니다. 약 71만명이 현재 카카오톡을 사용중이라고 하는군요.

카카오톡 평균 친구 수

카카오톡 회원들은 평균 65명의 친구를 가지고 있고 이들이 하루에 보내는 카톡 메시지는 지난 9월 현재, 6억개를 돌파했다고 합니다. 일인당 하루 평균 약 24의 카톡 메시지를 보내는 셈이죠. 이렇게 많은 메시지를 카톡으로 주고 받으니 이를 이통사 문자 메시지로 환산하면 매일 엄청난 수익이 이통사 주머니에서 사라지는 셈입니다. 

카카오톡 메시지 전송량

그렇게 생각하니 이통사들이 메시징 앱을 미워할만도 합니다. 하지만 대세는 거스를수 없는 법, 이통사들도 이에 대항해 자체적인 메시징 앱을 개발해 내놓았거나 출시할 예정입니다. 또한, 내년 초에는 3사 메시징 앱이 서로 연동되도록 할 방침이어서 무료 메시징 앱을 놓고 카카오톡과 한판 승부를 벌일 것으로 보입니다.
(관련 기사 - "카톡-애플 비켜!"…통신3사 '무료문자 대 연합')

아이메시지(iMessage)

이통 3사들이 이러한 조치를 하는 이유는 카카오톡 뿐 아니라 며칠전 업데이트된 애플의 iOS5가 제공하는 iMessage (아이메시지)에도 있습니다. 애플의 아이메시지는 아이폰이나 아이패드, 아이팟터치등 iOS5를 사용할수 있는 기기라면 와이파이를 이용해 무료로 사용할수 있는 메시지 기능이죠. 애플 기기 간 메신저 역할을 하는 아이메시지는 카카오톡에게도 경계해야 할 대상입니다. 


카카오톡은 계속되는 성장세에 힙입어 지난 7월 일본 법인도 설립했다고 합니다. 지원언어도 지금까지의 영어, 일본어 지원에서 총 10개국 언어 지원을 시작했다고 하는군요. 10월 12일부터 지원되는 10개국 언어는 중국어 (번체/간체)와 태국어, 터키어, 독일어, 프랑스어, 포르투갈어, 이탈리아어 등입니다.

카카오톡 지원 언어

또한, 지원하는 플랫폼을 보면 현재 아이폰, 안드로이드폰을 지원하고 있고 블랙베리는 오픈베타를 진행중이어서 크로스 플랫폼을 지원합니다. 이는 아이메시지가 iOS만 지원하는것에 비해 유리하게 작용하는 점이죠.

카카오톡 지원 플랫폼

이제범 대표는 카카오톡의 전체적인 서비스 개선 방안에 대해서도 얘기했는데 “올초부터 진행했던 ‘사용자 100가지 기능 개선 프로젝트’를 통해 약 6만건의 개선 제안 사항을 받아 하나씩 적용해 나가고 있다고 합니다.
 

사용자 100가지 기능 개선 프로젝트중 대표적인 것으로는 이모티콘 기능 추가, 장애인을 위한 보이스 오버 기능, 어르신들을 위한 폰트 크기 확대 기능 등이 기억나는군요. 

카카오톡 이모티콘

그리고, ‘겁나 빠른 황소’로 명명된 속도 개선 프로젝트를 통해 메시지 전송 속도를 약 20배 정도 향상시켰다고 합니다. 겁나 빠른 황소 프로젝트는 안정성 확보를 위해 조금씩 적용 대상자를 늘려나갈 계획이라고 하는데 개인적으로 확인해 보니 아직 저에게 까지는 적용이 안된것 같아 조금 더 기다려야 할것 같습니다. 

카카오톡 겁나 빠른 황소

사실 이날 가장 관심 있던 내용은 카카오톡이 플랫폼으로 전환한다는 내용이었습니다. 카카오톡의 플랫폼 전환은 그동안 별다른 수익을 내지 못했던 카카오톡에게는 수익을 올리며 보다 좋은 서비스를 오랫동안 제공할수 있는 밑바탕이 될것이기 때문이죠.

카톡해

그동안 "문자해~"라는 말대신 "카톡해~"라는 말을 하게 될 정도로 카카오톡의 성장은 눈부셨던게 사실입니다. 하지만 수익없이 투자만으로 서비스가 계속될수는 없기에 카카오톡의 수익 모델이 어떤 모습일지 많이 궁금했습니다.

카카오톡 플랫폼

카카오톡이 이날 내놓은 플랫폼 두가지는 아직 수익을 확실하게 낸다고 할수는 없지만 그 바탕이 될수는 있어 보였습니다. 하나는 "플러스 친구"이고 다른 하나는 "카카오 링크 2.0"입니다. 

플러스 친구는 카카오톡 친구 리스트에 좋아하는 브랜드나 스타, 미디어등을 추가해 이들이 제공하는 다양한 컨텐츠, 쿠폰, 이벤트 정보등을 받아 볼수 있는 플랫폼이죠.

카카오톡 플러스 친구

플러스 친구는 현재 21개 파트너들이 제공하는 정보를 받아 볼수 있으며 앞으로도 계속 추가될것이라고 합니다. 플러스 친구 파트너 리스트는 아래와 같으며 자세한 내용은 여기(링크 클릭)에서 확인할수 있으니 관심 있는 분들은 찾아가 보시면 됩니다.

카카오톡 플러스 친구 리스트

플러스 친구는 카카오톡을 실행하고 친구추천 탭을 열어 그곳에서 추가할수 있으며 플러스 친구를 추가하면 각종 무료 쿠폰을 받을수 있고 이벤트 정보 및 추가 혜택도 받을수 있습니다. 플러스 친구는 일종의 광고 플랫폼으로 성장할 가능성을 보이고 있지만 아직까지는 이를 통해 수익을 낼수 있을지는 확실하지 않다고 합니다.

카카오톡 플러스 친구

현재 플러스 친구에게는 메시지를 보낼수 없고 앞으로 가능하도록 할 계획이라고 하는군요. 또한, 플러스 친구를 통한 개인 정보 유출이 걱정될수 있는데 카카오측에서는 개인의 이름이나 전화번호는 플러스친구를 운영하는 파트너들에게 전달되지 않는다고 합니다. 

개인정보 유출은 극도로 민감한 사항이니 카카오측에서 신경을 많이 썼으리라고 생각하지만 앞으로도 대비를 철저히 해 네이트 개인정보 유출과 같은 사고가 다시는 발생하지 않기를 바랍니다. 플러스 친구가 사용자, 광고주, 카카오톡 모두에게 혜택이 돌아가는 윈윈 프로젝트로 성장할수 있을지 기대가 되는군요.

카카오 링크 2.0

이어 소개된 카카오링크 2.0은 외부 어플리케이션이나 모바일 웹페이지에서 카카오톡으로 링크를 보낼수 있는 API로 카카오링크 1.0은 외부 링크를 모바일 웹으로만 연결했지만 2.0에서는 모바일웹뿐 아니라 앱에서 앱으로 직접 연동도 가능하도록 했다고 하는군요. 
카카오 링크 2.0 적용 예 - 일루와카카오 링크 2.0 적용 예 - 벅스

카카오링크 2.0은 애플리케이션 개발사를 위한 플랫폼으로 카카오톡 친구와 다른 앱에서 음악, 지도, 게임 등의 콘텐츠를 함께 즐길 수 있도록 하는 기능이 있다고 합니다. 예를 들어 모바일 게임을 즐기다가 친구와 함께 게임을 하고 싶을 때 카카오톡을 통해 초대 메시지를 보내면 링크를 통해 앱이 실행되어 함께 게임을 플레이할 수 있으며 음악이나 동영상 등도 공유할 수 있다고 합니다. 또, "일루와"라는 아이폰 앱에도 카카오 링크 2.0이 적용되어 있어 지도상의 위치를 카카오톡 메시지를 통해 전송할수 있다고 하는군요. 카카오 링크가 적용되어 있는 앱이 어떤것인지 궁금하다면 카카오 링크 홈페이지에서 확인할수 있습니다.

카카오톡 플랫폼
카카오톡이 플랫폼 서비스로 전환되어 수익을 낼수 있는 모습으로 변신한 것에 대해 일단은 긍정적이라는 생각이 듭니다. 앞으로 사용자 약관 강제 동의 논란같은 악재가 다시는 나오지 않기를 바라고, 보다 사용자를 생각하는 user-friendly한 서비스를 제공해 주었으면 하는게 개인적인 바람이며 성공적인 수익모델을 만들어 주기를 기대합니다.

한마디 더> 이날 이제범 대표의 얘기는 잘 들었습니다. 하지만 발표시간 내내 너무 스크린에 가까이 계셔서 사진 찍기가 너무 어려웠습니다. 앞으로는 사진 찍는 사람을 위해 조금만 더 배려해 주셨으면 감사하겠네요. ^^