欢迎转载,务必注明出处:http://blog.csdn.net/wang_shuai_ww/article/details/44416041
eclipse完整工程下载地址:http://download.csdn.net/detail/u010406724/8515359
本篇是在本系列前三篇的基础上做的。记录尽量做的完善,读者在阅读本篇时,请确保前面的驱动和抽象层都已经编译没问题,且在开发板上能够正确跑起来,免得在参阅本篇文章写自己的程序时出现莫名的错误。
本篇将会介绍两种APP的编译方法,不过编写代码还是需要在eclipse中进行的。
在前面第二篇文章中我们知道,我们为app上层应用创建了一个java类接口服务ILedService,所以我们在编写配套的应用程序时需要这个类才行。我们知道eclipse使用的官方sdk是不含有我们自己创建的ILedService服务的,这个服务只存在于我们编译的Android源码中。为此我们需要我们建立的eclipse工程能够引用我们创建的ILedService类。
我网上搜索以及按照自己的理解尝试了不少的方法,最后找到了这篇文章http://blog.csdn.net/beihai1212/article/details/8782700,介绍的还是很不错的,经过尝试,我选择了这篇文章的第二种方法,看着比较官方,O(∩_∩)O。其实管理起来也方便,下次再使用时直接添加就可以了。
下面介绍怎么使用我们创建的ILedService类。
1.首先找到编译好的源码目录下的out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\classes.jar这个文件,把它拷贝到eclipse所在的系统平台,我eclipse使用的是Windows平台。为了好管理,我就在官方sdk的platforms目录下建立一个文件夹android-realarm来存放classes.jar这个文件,如下图所示:
一般来说我们只需要classes.jar所包含的类就足够使用了,其他的就不需要了。
下面就介绍怎么来写app应用和编译了
1.首先创建一个简单的工程,我命名为LedTest,具体的步骤就不再写了,注意在选择Target SDK和Compile With时要选择API19,即Android4.4的版本,创建好的工程如下图所示:
设置图示:
工程图示:
2.添加我们自己的classes.jar类库
(1)右键工程名,选择下图所示的红圈:
(2)在Libraries栏,选择Add Library
(3)然后是User Library,点击next,选择User Libraries,点击new,填写一个库的名字,我的是android-realarm,下面的System library要勾上,确定,之后如下图所示:
(3)点击Add External JAR,弹出对话框,选择我们前面存储的xxx\sdk\platforms\android-realarm\classes.jar文件,如下图所示:
(4)OK确认,然后Finish,完成设置,这时这个classes类库添加进我们的工程了,如下图:
(5)选择下图的红色部分,并点击进入:
(6)右边有up选项,把android-realarm移动到Android 4.4.2前面即可。
(7)OK确定,回到工程,确认库的添加,如下图:
如果结果如上图所示,那么就说明我们需要的类库添加成功了,那么下面我们就可以写程序了。
(8)MainActivity.java代码如下:
package com.example.ledtest; import android.app.Activity; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ImageView; import android.widget.ToggleButton; import android.os.ILedService; public class MainActivity extends Activity { private final static String LOG_TAG = "sean.realarm.led.activity"; private ILedService ledservice = null; private ToggleButton btnLed; private ImageView imageLed; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnLed = (ToggleButton) findViewById(R.id.btnLed); imageLed = (ImageView) findViewById(R.id.imageLed); ledservice = ILedService.Stub.asInterface(ServiceManager.getService("led")); try { Log.i(LOG_TAG, "Exception while reading value from led service0."); imageLed.setImageResource(R.drawable.bulboff); ledservice.setOff(0); } catch (RemoteException e) { Log.e(LOG_TAG, "Remote Exception while reading value from led service0."); } btnLed.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { if(btnLed.isChecked()){ try { Log.i(LOG_TAG, "Exception while reading value from led service1."); imageLed.setImageResource(R.drawable.bulbon); ledservice.setOn(0); } catch (RemoteException e) { Log.e(LOG_TAG, "Remote Exception while reading value from led service1."); } } else{ try { Log.i(LOG_TAG, "Exception while reading value from led service2."); imageLed.setImageResource(R.drawable.bulboff); ledservice.setOff(0); } catch (RemoteException e) { Log.e(LOG_TAG, "Remote Exception while reading value from led service2."); } } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }代码中我引用了图片资源,如果读者不想使用图片,把含有图片的代码注释掉就行了。也就不会报错了。
(9)主布局文件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.example.ledtest.MainActivity" > <ToggleButton android:id="@+id/btnLed" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/imageLed" android:layout_alignRight="@+id/imageLed" android:layout_centerVertical="true" android:textOff="开灯" android:textOn="关灯" /> <ImageView android:id="@+id/imageLed" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/btnLed" android:layout_centerHorizontal="true" android:layout_marginBottom="22dp" android:src="@drawable/bulboff" /> </RelativeLayout>
我的编译运行截图如下:
关闭灯的状态:
打开灯的状态:
当然了,同时观察开发板的LED灯状态,跟这个是同步的。
二、Android源码中编译工程文件文件
这个比eclipse是简单一些,不需要因为库的问题头疼。但是代码的编写可能没有在eclipse下编译时方便了,因为不知道哪里的代码写的有没有错误,对于小工程来说还好,大的话,估计是个人都会疯掉了。推荐使用上面的方法。
不过我这里还是简单说一下方法。
这里我就直接使用上面eclipse编辑的代码了,在Android源码下编译只需要res、src、AndroidManifest.xml、Android.mk、proguard.cfg、project.properties这几个文件,其他都不需要拷贝。
当然这里是缺少Android.mk文件,下面给出源码,拷贝保存一些即可:
TOP_LOCAL_PATH:= $(call my-dir) # Build activity LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := eng LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := LedTest LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) # ============================================================ # Also build all of the sub-targets under this one: the shared library. include $(call all-makefiles-under,$(LOCAL_PATH))
然后在终端进入Android源码根目录使用mmm ./packages/apps/LedTest/进行编译,完成后在out/target/product/realarm/system/app目录下就会生成LedTest.apk文件,把该文件push到开发板测试一下,当然了,跟eclipse的效果是一样的。
从eclipse拷贝源码到Android目录下编译不会出错的,大家放心好了,O(∩_∩)O~。
到此Android从底层到顶层的整个流程都记录完毕了,读者有什么疑问可以留言。能力有限,错误难免,大家见谅哈,勿喷。