前一段时间写了一个在Android中加入AdMob的博客,详见http://my.oschina.net/noahxiao/blog/61987

还有一个用Scala开发Android应用-使用trait与implicit优化Activity,详见http://my.oschina.net/noahxiao/blog/61720

首先说明一下,我在android下是采用scala语言开发的。并不想讨论太多语言的好坏。只是把我开发时的经验与大家分享一下。

class ScalaAndroidActivity extends Activity with AdMobAdvertising with TestDataSource1 with TestDataSource2

大家先不要晕scala语言的继承关系是可以这样写的。with...

1、trait AdMobAdvertising

package org.noahx.commonimport FindView._import android.app.Activityimport android.widget.LinearLayoutimport com.google.ads.AdViewimport com.google.ads.AdSizeimport com.google.ads.AdRequestimport android.os.Bundletrait AdMobAdvertising extends Activity with FindView {  def adLinearLayout: LinearLayout    def adUnitId:String="a14xxxxxxxxxx"  lazy val adView = new AdView(this, AdSize.BANNER, adUnitId)  override def onCreate(savedInstanceState: Bundle) = {    super.onCreate(savedInstanceState)    adLinearLayout.addView(adView)    adView.loadAd(new AdRequest())  }  override def onDestroy() = {    if (adView != null) {      adView.destroy()    }    super.onDestroy()  }}

以上就是我写的trait,这样我们可以不用太多考虑AdMob本身,只要实现adLinearLayout这个方法就可以了。来看看Activity

package org.noahx.scalaandroidimport android.app.Activityimport android.os.Bundleimport android.widget.Buttonimport android.widget.TextViewimport android.view.Viewimport org.noahx.common.FindView._import android.widget.LinearLayoutimport com.google.ads.AdViewimport com.google.ads.AdSizeimport com.google.ads.AdRequestimport org.noahx.common.AdMobAdvertisingclass ScalaAndroidActivity extends Activity with AdMobAdvertising {  lazy val text = findView[TextView](R.id.text1)  lazy val button = findView[Button](R.id.button1)  override def adLinearLayout = findView[LinearLayout](R.id.adLinearLayout) //注意这里决定AdMob放在哪个LinearLayout中  override def onCreate(savedInstanceState: Bundle) = {    setContentView(R.layout.main)  //这个要放在super之前    super.onCreate(savedInstanceState)    button.onClick { view: View =>      text.setText("hello scala1!!!")    }  }}

用这样一个AdMobAdvertising的trait只要在想加入AdMob的Activity中with一下,指定一个LinearLayout就可以了。

是不是看上去很干净

当然如果你的adUnitId号是变动的也可以override掉,在Activity中加入如下代码

override def adUnitId="xxxxxxxxxxxxxxxx"

2、trait BaseDataSource

在做完上面的模式后我在想,是不是访问sqlite数据时也可以这样来写呢

我们先看看BaseDataSource

package org.noahx.commonimport android.app.Activityimport android.database.sqlite.SQLiteDatabaseimport android.database.sqlite.SQLiteOpenHelperimport android.os.Bundletrait BaseDataSource extends Activity {  def getSQLiteOpenHelper(): SQLiteOpenHelper  val sqliteOpenHelper = getSQLiteOpenHelper()  var database: SQLiteDatabase = null    def getDatabase()=database  private def open() = {    database = sqliteOpenHelper.getWritableDatabase()  }  private def close() = {    database.close()  }  override def onCreate(savedInstanceState: Bundle) = {    super.onCreate(savedInstanceState)    open()  }  override def onResume() = {    open()    super.onResume()  }  override def onPause() {    close()    super.onPause()  }  override def onDestroy() = {    close()    super.onDestroy()  }}

我们可以看到这个也是继承Activity,里面已经定义好了何时创建连接,何时关闭连接。缺少的只是getSQLiteOpenHelper没有实现

下面我们来看看SQLiteOpenHelper,这个目前本身没什么特点。

package org.noahx.scalaandroidimport android.database.sqlite.SQLiteOpenHelperimport android.database.sqlite.SQLiteDatabase.CursorFactoryimport android.content.Contextimport android.database.sqlite.SQLiteDatabaseimport android.util.Logclass TestSQLiteOpenHelper(context: Context, dbName: String, cFactory: CursorFactory, ver: Int) extends SQLiteOpenHelper(context: Context, dbName: String, cFactory: CursorFactory, ver: Int) {  val databaseCreateTest1 = "create table test1 (id integer primary key autoincrement, name text not null)"  val databaseCreateTest2 = "create table test2 (id integer primary key autoincrement, name text not null)"  def this(context: Context) = {    this(context, "test.db", null, 1)  }  override def onCreate(database: SQLiteDatabase) = {    database.execSQL(databaseCreateTest1)    database.execSQL(databaseCreateTest2)  }  override def onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) = {    Log.w(classOf[TestSQLiteOpenHelper].getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data")    db.execSQL("DROP TABLE IF EXISTS " + "test1")    db.execSQL("DROP TABLE IF EXISTS " + "test2")    onCreate(db)  }}

下面我们要基于BaseDataSource写自己的DataSource了,这才是重点

(scala语言的定义与文件名无关,可以一个.scala文件中写多个class,trait,object,甚至全部程序写一个.scala文件中)

package org.noahx.scalaandroidimport org.noahx.common.BaseDataSourceimport scala.collection.mutable.ListBufferimport android.content.ContentValuestrait TestBaseDataSource extends BaseDataSource {  def getSQLiteOpenHelper() = new TestSQLiteOpenHelper(this)}trait TestDataSource1 extends TestBaseDataSource {  private val tableName = "test1"  def createTest1(name: String) = {    val values = new ContentValues()    values.put("name", name)    val insertId = database.insert(tableName, null, values)  }  def getTest1s(): List[String] = {    var words = new ListBuffer[String]    val cursor = database.query(tableName, Array("name"), null, null, null, null, null)    cursor.moveToFirst()    while (!cursor.isAfterLast()) {      words += cursor.getString(0)      cursor.moveToNext()    }    cursor.close()    words.toList  }}trait TestDataSource2 extends TestBaseDataSource {  private val tableName = "test2"  def createTest2(name: String) = {    val values = new ContentValues()    values.put("name", name)    val insertId = database.insert(tableName, null, values)  }  def getTest2s(): List[String] = {    var words = new ListBuffer[String]    val cursor = database.query(tableName, Array("name"), null, null, null, null, null)    cursor.moveToFirst()    while (!cursor.isAfterLast()) {      words += cursor.getString(0)      cursor.moveToNext()    }    cursor.close()    words.toList  }}

首先定义了TestBaseDataSource来统一设置helper,然后TestDataSource1与TestDataSource2就可以直接使用database这个对象了

来看看最终的Activity吧

package org.noahx.scalaandroidimport android.app.Activityimport android.os.Bundleimport android.widget.Buttonimport android.widget.TextViewimport android.view.Viewimport org.noahx.common.FindView._import android.widget.LinearLayoutimport com.google.ads.AdViewimport com.google.ads.AdSizeimport com.google.ads.AdRequestimport org.noahx.common.AdMobAdvertisingimport android.util.Logclass ScalaAndroidActivity extends Activity with AdMobAdvertising with TestDataSource1 with TestDataSource2 {  lazy val text = findView[TextView](R.id.text1)  lazy val button = findView[Button](R.id.button1)    override def adLinearLayout = findView[LinearLayout](R.id.adLinearLayout)  override def onCreate(savedInstanceState: Bundle) = {    setContentView(R.layout.main)    super.onCreate(savedInstanceState)        for(i <-0 to 10){      createTest1("test1."+i)      createTest2("test2."+i)    }    button.onClick { view: View =>      text.setText("hello scala!!!")            Log.i(classOf[ScalaAndroidActivity].getName(),getTest1s().toString())      Log.i(classOf[ScalaAndroidActivity].getName(),getTest2s().toString())    }  }}

这样的效果就是如果哪个Activity想用TestDataSource1,就直接加到父行为中,并在这个Activity中可以直接调用如:createTest1这样的方法直接操作数据库

由以下代码来写数据库

for(i <-0 to 10){      createTest1("test1."+i)      createTest2("test2."+i)    }

onClick时由Log输出结果

      Log.i(classOf[ScalaAndroidActivity].getName(),getTest1s().toString())      Log.i(classOf[ScalaAndroidActivity].getName(),getTest2s().toString())

后台打印结果如下

更多相关文章

  1. Android studio 自定义多选框CheckBox
  2. 自定义Spinner下拉菜单(下拉列表框)样式
  3. 白话开发——Android Studio代码调试技巧篇
  4. Android设置EditText显示输入的表情Icon(自定义的聊天有个发送表
  5. android的系统权限定义
  6. 自定义SeekBar样式
  7. Windows XP下git通过代理下载android代码

随机推荐

  1. android判断手机有没有安装微博
  2. java android 获取手机操作系统相关信息
  3. android图层划分(PhoneWindowManager.win
  4. Android读取XML文件(SAX)
  5. android 跳转并传递参数
  6. openGL ES学习教程 ---基本图像绘制
  7. android通知栏响应事件
  8. WiFi的使用Demo
  9. Android 定时启动应用
  10. Android之File内部存储和File外部存储