프로그래밍/Android

Android Application 11번가 검색 OPEN API 적용하기

2016. 8. 11. 15:09


Android Application 


11번가 검색 OPEN API 적용하기  



안녕하세요 

오늘은 Android Application에 11번가 검색 OPEN API를 적용해보겠습니당 



저는 eclipse에서 만들었습니다.

android application project를 생성해주세요! 


11번가 

OPEN API 사이트입니다 

http://openapi.11st.co.kr/openapi/OpenApiMain.tmall?method=getNoticeBoardList&unityBrdNo=18


로그인하셔서 OPEN API 사용 등록하시고 키 값을 받으셔야합니당 



1. activity_main.xml 파일을 작성합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" 
    android:orientation="vertical">
 
    <RelativeLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <EditText 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:hint="검색어"
            android:id="@+id/main_keyword_edt"
            android:layout_toLeftOf="@+id/main_search_btn"
            />
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/main_search_btn"
            android:text="검색"
            android:layout_alignParentRight="true"
            />
    </RelativeLayout>
    <ListView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/main_listView"
        ></ListView>
</LinearLayout>
 
cs

2

2. mainActivity.java 화면이 잘 나오는지 확인합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class MainActivity extends Activity {
    private EditText keywordEdt;
    private Button searchBtn;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        keywordEdt = (EditText)findViewById(R.id.main_keyword_edt);
        searchBtn = (Button) findViewById(R.id.main_search_btn);
        
        searchBtn.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                
            }
        });
    }
 
}
 
 
cs


3. list_product_item.xml 작성합니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package kr.mulcam.kyj.p0811;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    
    <ImageView
        android:layout_width="48dp"
        android:layout_height="48dp"
       android:id="@+id/product_img"
        android:text="이미지" />
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" 
        android:paddingLeft="3dp"
        >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:id="@+id/product_productName"
        android:text="상품명" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/product_price"
        android:text="가격" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/product_seller"
        android:text="판매자" />
    
    </LinearLayout>
   
</LinearLayout>
 
cs


4. 11번가 상품에 대한 모델클래스를 만들어주기 위하여 Product.java를 만들어주세요 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
 
public class Product {
    private String productCode;
    private String productName;
    private String productImage;
    private String productDetailUrl;
    private String productPrice;
    private String seller;
    private String rating;
    private String salePrice;
    private String delivery;
    private String reviewCount;
    private String buySatisfy;
    private String benefit;
    
    @Override
    public String toString() {
        return "Product [productCode=" + productCode + ", productName=" + productName + ", productImage=" + productImage
                + ", productDetailUrl=" + productDetailUrl + ", productPrice=" + productPrice + ", seller=" + seller
                + ", rating=" + rating + ", salePrice=" + salePrice + ", delivery=" + delivery + ", reviewCount="
                + reviewCount + ", buySatisfy=" + buySatisfy + ", benefit=" + benefit + "]";
    }
 
    public String getProductCode() {
        return productCode;
    }
 
    public void setProductCode(String productCode) {
        this.productCode = productCode;
    }
 
    public String getProductName() {
        return productName;
    }
 
    public void setProductName(String productName) {
        this.productName = productName;
    }
 
 
 
    public String getProductDetailUrl() {
        return productDetailUrl;
    }
 
    public void setProductDetailUrl(String productDetailUrl) {
        this.productDetailUrl = productDetailUrl;
    }
 
    public String getProductPrice() {
        return productPrice;
    }
 
    public void setProductPrice(String productPrice) {
        this.productPrice = productPrice;
    }
 
    public String getSeller() {
        return seller;
    }
 
    public void setSeller(String seller) {
        this.seller = seller;
    }
 
    public String getRating() {
        return rating;
    }
 
    public void setRating(String rating) {
        this.rating = rating;
    }
 
    public String getSalePrice() {
        return salePrice;
    }
 
    public void setSalePrice(String salePrice) {
        this.salePrice = salePrice;
    }
 
    public String getDelivery() {
        return delivery;
    }
 
    public void setDelivery(String delivery) {
        this.delivery = delivery;
    }
 
    public String getReviewCount() {
        return reviewCount;
    }
 
    public void setReviewCount(String reviewCount) {
        this.reviewCount = reviewCount;
    }
 
    public String getBuySatisfy() {
        return buySatisfy;
    }
 
    public void setBuySatisfy(String buySatisfy) {
        this.buySatisfy = buySatisfy;
    }
 
    public String getBenefit() {
        return benefit;
    }
 
    public void setBenefit(String benefit) {
        this.benefit = benefit;
    }
 
    public String getProductImage() {
        return productImage;
    }
 
    public void setProductImage(String productImage) {
        this.productImage = productImage;
    }
 
 
    
}
 

cs


5. ProductSearchService.java 작성해줍니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package kr.mulcam.kyj.p0811;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
 
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
 
public class ProductSearchService {
    
    // 요청할 URL
    private static final String URL = "http://openapi.11st.co.kr/openapi/OpenApiService.tmall?key=각자의키값입력=ProductSearch&keyword=";
 
    // 검색할 키워드
    private String keyword;
 
    public ProductSearchService(String keyword){
            this.keyword = keyword;
        }
 
    public void nextPage() {
        currentSkip += DISPLAY_ITEM_COUNT;
    }
 
    public List<Product> search() {
        List<Product> list = null;
        try {
            URL url;
            url = new URL(URL  + URLEncoder.encode(keyword, "EUC-KR"));
 
            URLConnection urlConn = url.openConnection();
 
            // xml파서객체만들고
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser parser = factory.newPullParser();
            // 요청에 대한 응답 결과를 파서에 세팅
            parser.setInput(new InputStreamReader(urlConn.getInputStream(),"EUC-KR"));
 
            int eventType = parser.getEventType();
            Product p = null;
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                case XmlPullParser.END_DOCUMENT: // 문서의 끝
                    break;
                case XmlPullParser.START_DOCUMENT:
                    list = new ArrayList<Product>();
                    break;
                case XmlPullParser.END_TAG: {
                    String tag = parser.getName();
                    if (tag.equals("Product")) {
                        list.add(p);
                        p = null;
                    }
                }
                case XmlPullParser.START_TAG: {
                    String tag = parser.getName();
                    switch (tag) {
                    case "Product":
                        p = new Product();
                        break;
                    case "ProductCode":
                        if (p != null)
                            p.setProductCode(parser.nextText());
                        break;
                    case "ProductName":
                        if (p != null)
                            p.setProductName(parser.nextText());
                        break;
                    case "ProductImage":
                        if (p != null)
                            p.setProductImage(parser.nextText());
                        break;
                    case "ProductPrice":
                        if (p != null)
                            p.setProductPrice(parser.nextText());
                        break;
                    case "Seller":
                        if (p != null)
                            p.setSeller(parser.nextText());
                        break;
                    case "Rating":
                        if (p != null)
                            p.setRating(parser.nextText());
                        break;
                    case "DetailPageUrl":
                        if (p != null)
                            p.setProductDetailUrl(parser.nextText());
                        break;
                    case "SalePrice":
                        if (p != null)
                            p.setSalePrice(parser.nextText());
                        break;
                    case "Delivery":
                        if (p != null)
                            p.setDelivery(parser.nextText());
                        break;
                    case "ReviewCount":
                        if (p != null)
                            p.setReviewCount(parser.nextText());
                        break;
                    case "BuySatisfy":
                        if (p != null)
                            p.setBuySatisfy(parser.nextText());
                        break;
                    }
 
                }
                }
                eventType = parser.next();
            }
 
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }
}
 
 
cs


6. ProductSearchThread.java 를 작성해줍니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package kr.mulcam.kyj.p0811;
 
import java.util.List;
 
import android.os.Handler;
import android.os.Message;
import android.util.Log;
 
public class ProductSearchThread extends Thread {
 
    private ProductSearchService service;
    private Handler handler;
        
    public ProductSearchThread(ProductSearchService service, Handler handler){
        this.service = service;
        this.handler = handler;
    }
 
    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        // service의 search메소드를 수행하고 결과를 핸들러를 통해 메인에게 전달
 
        List<Product> data = service.search();
        Message msg = handler.obtainMessage();
        msg.what = 1;
        msg.obj = data;
//        Log.d("YJ", data.get(0).getProductName());
        if (service.getCurrentSkip() == 1)
            msg.arg1 = 10;
        else
            msg.arg2 = 20;
        handler.sendMessage(msg);
    }
}
 
cs


7. ProductAdaper.java를 작성해줍니다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package kr.mulcam.kyj.p0811;
 
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
 
public class ProductAdapter extends ArrayAdapter<Product> {
    private Context context; 
    private int resource;
    private List<Product> productList;
    private ImageLoader imageLoader;
    public ProductAdapter(Context context, int resource, List<Product> productList) {
        super(context, resource,productList);
        // TODO Auto-generated constructor stub
        this.context = context; 
        this.resource = resource;
        this.productList = productList;
        imageLoader= new ImageLoader(context);
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
//        return super.getView(position, convertView, parent);
        
        //getView메소드는 리스트뷰의 한줄의 아이템을 그리기 위한 뷰를 만들어내는 함수이고 
        //한줄의 아이템에 대해서 UI를 인플레이션하고 그 객체를 리턴하면됨 
        
        ProductViewHolder holder;
        if(convertView == null){
            //이미 인플레이션 한 뷰가 있다면 매개변수 convertView에 들어와 재사용 가능하므로 
            //convertView가 null일때만 인플레이션 해줌 
            LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflate.inflate(R.layout.list_product_item, parent, false);
            holder = new ProductViewHolder();
            holder.imageView 
            = (ImageView) convertView.findViewById(R.id.product_img);
            holder.productName
            = (TextView) convertView.findViewById(R.id.product_productName);
            holder.productPrice
            = (TextView) convertView.findViewById(R.id.product_price);
            holder.productSeller
            = (TextView) convertView.findViewById(R.id.product_seller);
            //처음 인플레이션 될 때 홀더 객체를 만들어서 
            //홀더 셋트의 위젯 참조변수들이 findViewById
        
            //holder객체는 각 위젯들이 findViewById한 결과들 집합 
            convertView.setTag(holder);
            
        
        }
        else{
            holder = (ProductViewHolder) convertView.getTag();
            
        }
        //getView 할 일 
        //1. 껍데기 인플레이션하기(convertView가 null아니면 재사용 가능) 
        //2. 껍데기 내부의 위젯들 객체 얻어도기 (findViewById)
        //3. 각 위젯에 데이터 바인딩하기 
 
        
        Product    p = productList.get(position);
        
        //여기부터 이제 홀더객체 안의 각  위젯에 book객체의 각 멤버면수값들이랑 바인딩하면 됨ㅇㅇ 
        holder.imageView.setImageResource(R.drawable.ic_launcher);
        holder.productName.setText(p.getProductName());
        holder.productPrice.setText("가격: " + p.getProductPrice());
        holder.productSeller.setText("판매자: " + p.getSeller());
        //book.getImage() < url에 접속해서 사진을 다운받아 디코딩해서 ImageView에 set 
        new ImageDownLoader(holder.imageView).execute(p.getProductImage());
//        imageLoader.DisplayImage(p.getProductImage(), holder.imageView);
 
        return convertView;
        
    }
    
    class ImageDownLoader extends AsyncTask<String, Void, Bitmap>
    {
        ImageView imageView;
        public ImageDownLoader(ImageView imageView){
            this.imageView = imageView;
        }
        
        @Override
        protected Bitmap doInBackground(String... params) {
            // TODO Auto-generated method stub
            Bitmap bitmap = null;
            try {
                URL url = new URL(params[0]);
                BufferedInputStream bi = new BufferedInputStream(url.openStream());
                bitmap = BitmapFactory.decodeStream(bi);
                bi.close();
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return bitmap;
        }
 
        @Override
        protected void onPostExecute(Bitmap result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            if(result != null)
                imageView.setImageBitmap(result);
        }
        
    }
    
    
    static class ProductViewHolder{
        public ImageView imageView;
        public TextView productName;
        public TextView productPrice;
        public TextView productSeller;
    }
    
 
}
 
 
cs


8. mainActivity.java 작성해줍니다.  


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package kr.mulcam.kyj.p0811;
 
import java.util.ArrayList;
import java.util.List;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
 
public class MainActivity extends Activity {
    private EditText keywordEdt;
    private Button searchBtn;
    private List<Product> productList;
    
    private ListView listView;
    private ProductAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        keywordEdt = (EditText)findViewById(R.id.main_keyword_edt);
        searchBtn = (Button) findViewById(R.id.main_search_btn);
        productList = new ArrayList<Product>();
        adapter = new ProductAdapter(this, R.layout.list_product_item, productList);
        listView = (ListView) findViewById(R.id.main_listView);
        
        listView.setAdapter(adapter);
        searchBtn.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                String keyword = keywordEdt.getText().toString();
                ProductSearchService service = new ProductSearchService(keyword);
                ProductSearchThread thread = new ProductSearchThread(service, handler);
                thread.start();
            }
        });
    }
    private Handler handler = new Handler(){
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            if(msg.what ==1 )
            {
                //arg1이 10이면 처음 검색에 대한 결과를 갖다 준걸로 
                if(msg.arg1==10)
                {
//                    String result = "";
//                    List<Product> data = (List<Product>)msg.obj;
//                    for(Product p : data)
//                        result += p.getProductName() +"\n";
//                    Toast.makeText(MainActivity.this, result, 0).show();
//                    Toast.makeText(MainActivity.this, "dd", 0).show();
                    productList.clear();
                    productList.addAll((List<Product>) msg.obj);
                    adapter.notifyDataSetChanged();
                }
//                arg2이 20이면 검색했던 결과에 대해 추가 아이템을 요청한걸로
                if(msg.arg2==20){
                    
                }
            }
        }
    };
    
}
 
 
cs



 String result = "";
//                    List<Product> data = (List<Product>)msg.obj;
//                    for(Product p : data)
//                        result += p.getProductName() +"\n";
//                    Toast.makeText(MainActivity.this, result, 0).show();
//                    Toast.makeText(MainActivity.this, "dd", 0).show();

+ 여기서 오류가 날 수 있기 때문에 toast를 찍어서 결과값이 제대로 나오는지 확인하고 
제대로 나온다면 그 아래 소스로 작성하면 됩니다. 


9. AndroidManifest.xml에 인터넷을 연결하기 때문에 permission을 추가해주시면 됩니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="kr.mulcam.kyj.p0811"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>
 
 
 
cs




결과 화면 











+

완성하면 이미지가 인터넷으로 받아오기 때문에 

계속 움직이는듯한 보기 불편한?! 
따라서 아래 소스를 참고해주세요! 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package kr.mulcam.kyj.p0811;
 
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
 
public class ProductAdapter extends ArrayAdapter<Product> {
    private Context context; 
    private int resource;
    private List<Product> productList;
    private ImageLoader imageLoader;
    public ProductAdapter(Context context, int resource, List<Product> productList) {
        super(context, resource,productList);
        // TODO Auto-generated constructor stub
        this.context = context; 
        this.resource = resource;
        this.productList = productList;
        imageLoader= new ImageLoader(context);
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
//        return super.getView(position, convertView, parent);
        
        //getView메소드는 리스트뷰의 한줄의 아이템을 그리기 위한 뷰를 만들어내는 함수이고 
        //한줄의 아이템에 대해서 UI를 인플레이션하고 그 객체를 리턴하면됨 
        
        ProductViewHolder holder;
        if(convertView == null){
            //이미 인플레이션 한 뷰가 있다면 매개변수 convertView에 들어와 재사용 가능하므로 
            //convertView가 null일때만 인플레이션 해줌 
            LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflate.inflate(R.layout.list_product_item, parent, false);
            holder = new ProductViewHolder();
            holder.imageView 
            = (ImageView) convertView.findViewById(R.id.product_img);
            holder.productName
            = (TextView) convertView.findViewById(R.id.product_productName);
            holder.productPrice
            = (TextView) convertView.findViewById(R.id.product_price);
            holder.productSeller
            = (TextView) convertView.findViewById(R.id.product_seller);
            //처음 인플레이션 될 때 홀더 객체를 만들어서 
            //홀더 셋트의 위젯 참조변수들이 findViewById
        
            //holder객체는 각 위젯들이 findViewById한 결과들 집합 
            convertView.setTag(holder);
            
        
        }
        else{
            holder = (ProductViewHolder) convertView.getTag();
            
        }
        //getView 할 일 
        //1. 껍데기 인플레이션하기(convertView가 null아니면 재사용 가능) 
        //2. 껍데기 내부의 위젯들 객체 얻어도기 (findViewById)
        //3. 각 위젯에 데이터 바인딩하기 
 
        
        Product    p = productList.get(position);
        
        //여기부터 이제 홀더객체 안의 각  위젯에 book객체의 각 멤버면수값들이랑 바인딩하면 됨ㅇㅇ 
//        holder.imageView.setImageResource(R.drawable.ic_launcher);
        holder.productName.setText(p.getProductName());
        holder.productPrice.setText("가격: " + p.getProductPrice());
        holder.productSeller.setText("판매자: " + p.getSeller());
        //book.getImage() < url에 접속해서 사진을 다운받아 디코딩해서 ImageView에 set 
//        new ImageDownLoader(holder.imageView).execute(p.getProductImage());
        imageLoader.DisplayImage(p.getProductImage(), holder.imageView);
 
        return convertView;
        
    }
    
    class ImageDownLoader extends AsyncTask<String, Void, Bitmap>
    {
        ImageView imageView;
        public ImageDownLoader(ImageView imageView){
            this.imageView = imageView;
        }
        
        @Override
        protected Bitmap doInBackground(String... params) {
            // TODO Auto-generated method stub
            Bitmap bitmap = null;
            try {
                URL url = new URL(params[0]);
                BufferedInputStream bi = new BufferedInputStream(url.openStream());
                bitmap = BitmapFactory.decodeStream(bi);
                bi.close();
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return bitmap;
        }
 
        @Override
        protected void onPostExecute(Bitmap result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            if(result != null)
                imageView.setImageBitmap(result);
        }
        
    }
    
    
    static class ProductViewHolder{
        public ImageView imageView;
        public TextView productName;
        public TextView productPrice;
        public TextView productSeller;
    }
    
 
}
 
 
cs



new ImageDownLoader(holder.imageView).execute(p.getProductImage());

위의 소스는 주석 처리해주시고! 

  imageLoader.DisplayImage(p.getProductImage(), holder.imageView);

아래부분을 작성해주시면 됩니당

위 소스를 사용하기 위해서는 4개 파일과 manafest에 소스코드추가가 필요합니다. 

아래에 소스코드를 추가해놓겠습니다.  


FileCache.java 작성합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package kr.mulcam.kyj.p0811;
 
 
import java.io.File;
import android.content.Context;
 
public class FileCache {
    
    private File cacheDir;
    
    public FileCache(Context context){
        //Find the dir to save cached images
        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
            cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
        else
            cacheDir=context.getCacheDir();
        if(!cacheDir.exists())
            cacheDir.mkdirs();
    }
    
    public File getFile(String url){
        //I identify images by hashcode. Not a perfect solution, good for the demo.
        String filename=String.valueOf(url.hashCode());
        //Another possible solution (thanks to grantland)
        //String filename = URLEncoder.encode(url);
        File f = new File(cacheDir, filename);
        return f;
        
    }
    
    public void clear(){
        File[] files=cacheDir.listFiles();
        if(files==null)
            return;
        for(File f:files)
            f.delete();
    }
 
}
 
cs


ImageLoader.java 작성합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
package kr.mulcam.kyj.p0811;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.os.Handler;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
 
public class ImageLoader {
    
    MemoryCache memoryCache=new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;
    Handler handler=new Handler();//handler to display images in UI thread
    
    public ImageLoader(Context context){
        fileCache=new FileCache(context);
        executorService=Executors.newFixedThreadPool(5);
    }
    
    final int stub_id=R.drawable.ic_launcher;
    public void DisplayImage(String url, ImageView imageView)
    {
        imageViews.put(imageView, url);
        Bitmap bitmap=memoryCache.get(url);
        if(bitmap!=null)
            imageView.setImageBitmap(bitmap);
        else
        {
            queuePhoto(url, imageView);
            imageView.setImageResource(stub_id);
        }
    }
        
    private void queuePhoto(String url, ImageView imageView)
    {
        PhotoToLoad p=new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }
    
    private Bitmap getBitmap(String url) 
    {
        File f=fileCache.getFile(url);
        
        //from SD cache
        Bitmap b = decodeFile(f);
        if(b!=null)
            return b;
        
        //from web
        try {
            Bitmap bitmap=null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is=conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            conn.disconnect();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Throwable ex){
           ex.printStackTrace();
           if(ex instanceof OutOfMemoryError)
               memoryCache.clear();
           return null;
        }
    }
 
    //decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f){
        try {
            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            FileInputStream stream1=new FileInputStream(f);
            BitmapFactory.decodeStream(stream1,null,o);
            stream1.close();
            
            //Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE=70;
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }
            
            //decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            FileInputStream stream2=new FileInputStream(f);
            Bitmap bitmap=BitmapFactory.decodeStream(stream2, null, o2);
            stream2.close();
            return bitmap;
        } catch (FileNotFoundException e) {
        } 
        catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    //Task for the queue
    private class PhotoToLoad
    {
        public String url;
        public ImageView imageView;
        public PhotoToLoad(String u, ImageView i){
            url=u; 
            imageView=i;
        }
    }
    
    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;
        PhotosLoader(PhotoToLoad photoToLoad){
            this.photoToLoad=photoToLoad;
        }
        
        @Override
        public void run() {
            try{
                if(imageViewReused(photoToLoad))
                    return;
                Bitmap bmp=getBitmap(photoToLoad.url);
                memoryCache.put(photoToLoad.url, bmp);
                if(imageViewReused(photoToLoad))
                    return;
                BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
                handler.post(bd);
            }catch(Throwable th){
                th.printStackTrace();
            }
        }
    }
    
    boolean imageViewReused(PhotoToLoad photoToLoad){
        String tag=imageViews.get(photoToLoad.imageView);
        if(tag==null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }
    
    //Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable
    {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;
        public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
        public void run()
        {
            if(imageViewReused(photoToLoad))
                return;
            if(bitmap!=null)
                photoToLoad.imageView.setImageBitmap(bitmap);
            else
                photoToLoad.imageView.setImageResource(stub_id);
        }
    }
 
    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }
 
}
 
cs



MemoryCache.java 작성합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package kr.mulcam.kyj.p0811;
 
 
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import android.graphics.Bitmap;
import android.util.Log;
 
public class MemoryCache {
 
    private static final String TAG = "MemoryCache";
    private Map<String, Bitmap> cache=Collections.synchronizedMap(
            new LinkedHashMap<String, Bitmap>(10,1.5f,true));//Last argument true for LRU ordering
    private long size=0;//current allocated size
    private long limit=1000000;//max memory in bytes
 
    public MemoryCache(){
        //use 25% of available heap size
        setLimit(Runtime.getRuntime().maxMemory()/4);
    }
    
    public void setLimit(long new_limit){
        limit=new_limit;
        Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB");
    }
 
    public Bitmap get(String id){
        try{
            if(!cache.containsKey(id))
                return null;
            //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
            return cache.get(id);
        }catch(NullPointerException ex){
            ex.printStackTrace();
            return null;
        }
    }
 
    public void put(String id, Bitmap bitmap){
        try{
            if(cache.containsKey(id))
                size-=getSizeInBytes(cache.get(id));
            cache.put(id, bitmap);
            size+=getSizeInBytes(bitmap);
            checkSize();
        }catch(Throwable th){
            th.printStackTrace();
        }
    }
    
    private void checkSize() {
        Log.i(TAG, "cache size="+size+" length="+cache.size());
        if(size>limit){
            Iterator<Entry<String, Bitmap>> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated  
            while(iter.hasNext()){
                Entry<String, Bitmap> entry=iter.next();
                size-=getSizeInBytes(entry.getValue());
                iter.remove();
                if(size<=limit)
                    break;
            }
            Log.i(TAG, "Clean cache. New size "+cache.size());
        }
    }
 
    public void clear() {
        try{
            //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
            cache.clear();
            size=0;
        }catch(NullPointerException ex){
            ex.printStackTrace();
        }
    }
 
    long getSizeInBytes(Bitmap bitmap) {
        if(bitmap==null)
            return 0;
        return bitmap.getRowBytes() * bitmap.getHeight();
    }
}
cs


 

Utils.java 작성합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package kr.mulcam.kyj.p0811;
 
import java.io.InputStream;
import java.io.OutputStream;
 
public class Utils {
    public static void CopyStream(InputStream is, OutputStream os)
    {
        final int buffer_size=1024;
        try
        {
            byte[] bytes=new byte[buffer_size];
            for(;;)
            {
              int count=is.read(bytes, 0, buffer_size);
              if(count==-1)
                  break;
              os.write(bytes, 0, count);
            }
        }
        catch(Exception ex){}
    }
}
cs


AndroidManifest.xml에 <uses-permission andriod:name="andriod permission.WRITE_EXTERNAL_STORAGE"/> 

작성해주면 끄으으으으읕납니다^0^