Android: Jsoup Kütüphanesi ve HTML Parser
Merhaba arkadaşlar,
Bugün Android ile html parse etme işlemini bunun içinde kullanacağımız jsoup kütüphanesinden bahsedeceğim. Bu dersi Eclipse ortamında anlatacağım. Öncelikle buradan Jsoup kütüphanesini indiriyoruz (jsoup-1.8.1.jar), indirdiğimiz jar dosyasını projemize dahil ettikten sonra artık kullanabiliriz. Peki ne işe yarar Jsoup kütüphanesi? Bu kütüphane ile hızlı bir şekilde html parse etme işlemi gerçekleştirilmektedir. Android uygulamalarda sıkça kullanılan RSS kaynaklardır, ancak bazı web sitelerinde RSS kaynağının bulunmaması bizi html parse etme işlemine sürükler. Bu yüzden bu kütüphaneyi kullanmayı tercih ve tavsiye ediyorum.
Öncelikle yapacağımız projenin kısa bir hikayesini yazalım. Bu projede oguzhanozdemir.com.tr web adresimin basit bir uygulamasını geliştirmeye çalışacağım. Uygulama içerisinde son yazıları listeyeceğiz. Yazılarımızın başlığı, adresi, resmi ve kısa içeriği bulunacaktır.
Jsoup kütüphanesinde istediğimiz alanların html ve css taglarını belirleyerek kaynak dosya içerisinde geçen verileri Element listesi olarak tutulmasını sağlıyoruz. Bu yüzden ilk işlemimiz sitemizdeki title, content, image gibi alanların taglarını belirlemek olacaktır. Sitemizin kaynak dosyasına göz atalım.
Şekilde sitemizde bizi sonuca ulaştıracak div tagları ve bu div tagları içerisinde img, h2, p gibi diğer son taglar işaretlenmiştir. Burada önemli olan nokta div taglarının özel isimleridir. Örneğin bazı div taglarının ID’lerini alırken bazılarının ise Class isimlerini alacağız. Diğer önemli nokta ise hızlı olması açısından her adımda bir alttaki tag’a ulaşacağız. Basamak basamak ilerleyeceğiz.
Şimdi uygulamamıza dönelim. Uygulamamızın ana sayfasında bir adet ListView bulunacaktır. Bu listview’in her satırının özel olan görselini ayarlayarak başlayabiliriz.
Üst kısımda yazımızın başlığı, hemen altında görselimiz ve altında da kısa içeriğimiz bulunacaktır. Seçilen itemin ayrıntısını görmek için ise görünmez olarak bulundurduğumuz bir textview nesnemiz daha vardır.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="5dp" android:orientation="vertical" > <TextView android:id="@+id/txtTitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Large Text" android:layout_gravity="center" android:layout_margin="2dp" android:textAppearance="?android:attr/textAppearanceLarge" /> <ImageView android:id="@+id/imagePost" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginBottom="2dp" android:src="@drawable/ic_launcher" /> <ir.noghteh.JustifiedTextView xmlns:noghteh="http://noghteh.ir" android:id="@+id/txtContent" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="left" android:layout_margin="2dp" noghteh:text="asdasd"> </ir.noghteh.JustifiedTextView> <TextView android:id="@+id/txtAddress" android:layout_width="fill_parent" android:layout_height="wrap_content" android:visibility="gone" android:text="TextView" /> </LinearLayout>
Kodlarımızda da görüldüğü gibi 3 adet textview ve 1 adet imageview nesnesi bulunmaktadır.(txtAddress id’li textview nesnemiz arkaplanda işimizi göreceği için visibility = gone yaptık). Ayrıca incelemenizi tavsiye ettiğim JustifiedTextView kütüphanesini de kullandım, bu kütüphane içerisinde barındırdığı paragrafı sağa ve sola yaslı olarak hizalamaktadır. Hızlı bir şekilde MainActivity’nin de arayüzünü oluşturan xml dosyasına göz atalım.
- activity_main.xml
<RelativeLayout 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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.ogzhnozdmr.jsouplib.MainActivity" > <ListView android:id="@+id/listPosts" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" > </ListView> </RelativeLayout>
Uygulama içerisinde activity_main.xml de bulunan listview ile verileri listeleyeceğiz. Gelen verileri ise oluşturacağımız bir nesne de tutmalıyız. Yani her bir satır 1 nesneyi ifade etmeli, bizim nesnemiz de Post olsun. Her post’umuzun bir başlığı, resmi, içeriği ve adresi bulunmaktadır demiştik. Bu bilgiler ışığında nesnemizin classını yazdık.
Şimdiki işlemimiz ise verileri kaynak dosyamızdan çekmek ve parse etmek. Yani asıl konumuza geldik. Genel itibariyle android programlama içerisinde web’den veri çekme işlemleri AsyncTask nesnesi ile arka planda yapılmaktadır. Bizde html parse işlemlerimizi AsyncTask ile yapacağız. İlk olarak 2 adet AsyncTask sınıfı oluşturuyoruz bu sınıfların kodlarını göstermeden önce gerçekleştirilecek işlemlerden bahsetmek istiyorum.(AsyncTask hakkında.)
İlk sınıfımız GetLastPosts sınıfı, bu sınıf String parametre alarak çalışmaktadır. Biz de parametre olarak sitemizin adresini vereceğiz, “http://www.oguzhanozdemir.com.tr”. AsyncTask sınıfı birkaç fonksiyondan oluşmaktadır. Bizde bu fonksiyonları Override ederek işlemlerimizi gerçekleştireceğiz. onPreExecute, doInBackground ve onPostExecute metotları. doInBackground metodunun en önemli 2 özelliği; yapılmak istenen işlemler burada gerçekleştirilir (örneğin webden veri çekmek..) diğeri ise bu metot içerisinde hiç bir şekilde arayüze müdahale edemiyoruz. Genellikle arayüze postExecute metodunda işlem sonunda gösterilmek istenen sonuçlar için müdahale edebiliyoruz. Son olarak onPreExecute metotunda ise progressDialog ile kullanıcıyı bilgilendiriyoruz.
GetLastPosts
Jsoup kütühanesinin bize sunduğu en büyük kolaylık burada karşımıza çıkıyor. Bu kısmı görsel üzerindeki açıklamalardan takip edebilirsiniz.
Son aşamada ise gelen verileri listview de gösterebilmek için özel bir adapter yazmamız gerekmektedir. Bu adapter post_row.xml dosyamızı listview’in her bir satırına adapte etmekte aynı zamanda içerisine verilen dataların nasıl konumlanacağını belirlemek için kullanılır.
- LastPostAdapter.java
public class LastPostsAdapter extends BaseAdapter { private LayoutInflater myInflater; private List<Post> myPosts; public LastPostsAdapter(Activity activity, List<Post> posts) { myInflater = (LayoutInflater) activity .getSystemService(Context.LAYOUT_INFLATER_SERVICE); myPosts = posts; } @Override public int getCount() { return myPosts.size(); } @Override public Object getItem(int position) { return myPosts.get(position); } @Override public long getItemId(int position) { return position; } @SuppressLint("ViewHolder") @Override public View getView(int position, View convertView, ViewGroup parent) { View row = null; Bitmap bitmap; row = myInflater.inflate(R.layout.post_row, null); JustifiedTextView content = (JustifiedTextView)row.findViewById(R.id.txtContent); TextView title = (TextView)row.findViewById(R.id.txtTitle); TextView address = (TextView)row.findViewById(R.id.txtAddress); //TextView content = (TextView)row.findViewById(R.id.txtContent); ImageView image = (ImageView)row.findViewById(R.id.imagePost); content.setAlignment(Align.LEFT); title.setText(myPosts.get(position).getTitle()); address.setText(myPosts.get(position).getAddress()); content.setText(myPosts.get(position).getShortContent()); image.setImageBitmap(myPosts.get(position).getImage()); return row; } }
Son olarak MainActivity içerisinde listview’e bu adapteri bağlamamız gerekiyor. Bu işlemi de aşağıda görüldüğü gibi tamamladıktan sonra projemiz tamamlanmış olmaktadır. Projenin çalışan hali şekildeki gibidir. Projenin kaynak kodları için ogzhnozdmr@gmail.com adresine mail atmanız yeterlidir. İyi çalışmalar.
LastPostsAdapter adapter = new LastPostsAdapter(MainActivity.this, lastPosts); lastPostsList.setAdapter(adapter);
emeğinize sağlık
İlginize teşekkür ederim.. Yeni yazılarımız yakında..
emailize kaynak kod isteğinde bulundum şimdiden teşekkürler
emeğinize sağlık teşekürler