展会信息港展会大全

无Java开发Android应用(NativeActivity)
来源:互联网   发布日期:2016-01-14 10:12:35   浏览:2431次  

导读:最新的 Android 2.3 无需 Java 就可以开发应用,详情请看 http://www.oschina.net/news/14732/android-ndk-updates-no-more-java-required。 ...

最新的 Android 2.3 无需 Java 就可以开发应用,详情请看 http://www.oschina.net/news/14732/android-ndk-updates-no-more-java-required。

这里是官方给的例子程序 ,来自:http://developer.android.com/reference/android/app/NativeActivity.html

[代码] AndroidManifest.xml

01

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

02

package="com.example.native_activity"

03

android:versionCode="1"

04

android:versionName="1.0">

05

06

<!-- This is the platform API where NativeActivity was introduced. -->

07

<uses-sdk android:minSdkVersion="8" />

08

09

<!-- This .apk has no Java code itself, so set hasCode to false. -->

10

<application android:label="@string/app_name" android:hasCode="false">

11

12

<!-- Our activity is the built-in NativeActivity framework class.

13

This will take care of integrating with our NDK code. -->

14

<activity android:name="android.app.NativeActivity"

15

android:label="@string/app_name"

16

android:configChanges="orientation|keyboardHidden">

17

<!-- Tell NativeActivity the name of or .so -->

18

<meta-data android:name="android.app.lib_name"

19

android:value="native-activity" />

20

<intent-filter>

21

<action android:name="android.intent.action.MAIN" />

22

<category android:name="android.intent.category.LAUNCHER" />

23

</intent-filter>

24

</activity>

25

</application>

26

27

</manifest>

[代码] Demo.c

001

#include <jni.h>

002

#include <errno.h>

003

004

#include <EGL/egl.h>

005

#include <GLES/gl.h>

006

007

#include <android/sensor.h>

008

#include <android/log.h>

009

#include <android_native_app_glue.h>

010

011

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))

012

#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))

013

014

/**

015

* Our saved state data.

016

*/

017

struct saved_state {

018

float angle;

019

int32_t x;

020

int32_t y;

021

};

022

023

/**

024

* Shared state for our app.

025

*/

026

struct engine {

027

struct android_app* app;

028

029

ASensorManager* sensorManager;

030

const ASensor* accelerometerSensor;

031

ASensorEventQueue* sensorEventQueue;

032

033

int animating;

034

EGLDisplay display;

035

EGLSurface surface;

036

EGLContext context;

037

int32_t width;

038

int32_t height;

039

struct saved_state state;

040

};

041

042

/**

043

* Initialize an EGL context for the current display.

044

*/

045

static int engine_init_display(struct engine* engine) {

046

// initialize OpenGL ES and EGL

047

048

/*

049

* Here specify the attributes of the desired configuration.

050

* Below, we select an EGLConfig with at least 8 bits per color

051

* component compatible with on-screen windows

052

*/

053

const EGLint attribs[] = {

054

EGL_SURFACE_TYPE, EGL_WINDOW_BIT,

055

EGL_BLUE_SIZE, 8,

056

EGL_GREEN_SIZE, 8,

057

EGL_RED_SIZE, 8,

058

EGL_NONE

059

};

060

EGLint w, h, dummy, format;

061

EGLint numConfigs;

062

EGLConfig config;

063

EGLSurface surface;

064

EGLContext context;

065

066

EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

067

068

eglInitialize(display, 0, 0);

069

070

/* Here, the application chooses the configuration it desires. In this

071

* sample, we have a very simplified selection process, where we pick

072

* the first EGLConfig that matches our criteria */

073

eglChooseConfig(display, attribs, &config, 1, &numConfigs);

074

075

/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is

076

* guaranteed to be accepted by ANativeWindow_setBuffersGeometry().

077

* As soon as we picked a EGLConfig, we can safely reconfigure the

078

* ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */

079

eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);

080

081

ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);

082

083

surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);

084

context = eglCreateContext(display, config, NULL, NULL);

085

086

if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {

087

LOGW("Unable to eglMakeCurrent");

088

return -1;

089

}

090

091

eglQuerySurface(display, surface, EGL_WIDTH, &w);

092

eglQuerySurface(display, surface, EGL_HEIGHT, &h);

093

094

engine->display = display;

095

engine->context = context;

096

engine->surface = surface;

097

engine->width = w;

098

engine->height = h;

099

engine->state.angle = 0;

100

101

// Initialize GL state.

102

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);

103

glEnable(GL_CULL_FACE);

104

glShadeModel(GL_SMOOTH);

105

glDisable(GL_DEPTH_TEST);

106

107

return 0;

108

}

109

110

/**

111

* Just the current frame in the display.

112

*/

113

static void engine_draw_frame(struct engine* engine) {

114

if (engine->display == NULL) {

115

// No display.

116

return;

117

}

118

119

// Just fill the screen with a color.

120

glClearColor(((float)engine->state.x)/engine->width, engine->state.angle,

121

((float)engine->state.y)/engine->height, 1);

122

glClear(GL_COLOR_BUFFER_BIT);

123

124

eglSwapBuffers(engine->display, engine->surface);

125

}

126

127

/**

128

* Tear down the EGL context currently associated with the display.

129

*/

130

static void engine_term_display(struct engine* engine) {

131

if (engine->display != EGL_NO_DISPLAY) {

132

eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

133

if (engine->context != EGL_NO_CONTEXT) {

134

eglDestroyContext(engine->display, engine->context);

135

}

136

if (engine->surface != EGL_NO_SURFACE) {

137

eglDestroySurface(engine->display, engine->surface);

138

}

139

eglTerminate(engine->display);

140

}

141

engine->animating = 0;

142

engine->display = EGL_NO_DISPLAY;

143

engine->context = EGL_NO_CONTEXT;

144

engine->surface = EGL_NO_SURFACE;

145

}

146

147

/**

148

* Process the next input event.

149

*/

150

static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {

151

struct engine* engine = (struct engine*)app->userData;

152

if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {

153

engine->animating = 1;

154

engine->state.x = AMotionEvent_getX(event, 0);

155

engine->state.y = AMotionEvent_getY(event, 0);

156

return 1;

157

}

158

return 0;

159

}

160

161

/**

162

* Process the next main command.

163

*/

164

static void engine_handle_cmd(struct android_app* app, int32_t cmd) {

165

struct engine* engine = (struct engine*)app->userData;

166

switch (cmd) {

167

case APP_CMD_SAVE_STATE:

168

// The system has asked us to save our current state.Do so.

169

engine->app->savedState = malloc(sizeof(struct saved_state));

170

*((struct saved_state*)engine->app->savedState) = engine->state;

171

engine->app->savedStateSize = sizeof(struct saved_state);

172

break;

173

case APP_CMD_INIT_WINDOW:

174

// The window is being shown, get it ready.

175

if (engine->app->window != NULL) {

176

engine_init_display(engine);

177

engine_draw_frame(engine);

178

}

179

break;

180

case APP_CMD_TERM_WINDOW:

181

// The window is being hidden or closed, clean it up.

182

engine_term_display(engine);

183

break;

184

case APP_CMD_GAINED_FOCUS:

185

// When our app gains focus, we start monitoring the accelerometer.

186

if (engine->accelerometerSensor != NULL) {

187

ASensorEventQueue_enableSensor(engine->sensorEventQueue,

188

engine->accelerometerSensor);

189

// We'd like to get 60 events per second (in us).

190

ASensorEventQueue_setEventRate(engine->sensorEventQueue,

191

engine->accelerometerSensor, (1000L/60)*1000);

192

}

193

break;

194

case APP_CMD_LOST_FOCUS:

195

// When our app loses focus, we stop monitoring the accelerometer.

196

// This is to avoid consuming battery while not being used.

197

if (engine->accelerometerSensor != NULL) {

198

ASensorEventQueue_disableSensor(engine->sensorEventQueue,

199

engine->accelerometerSensor);

200

}

201

// Also stop animating.

202

engine->animating = 0;

203

engine_draw_frame(engine);

204

break;

205

}

206

}

207

208

/**

209

* This is the main entry point of a native application that is using

210

* android_native_app_glue.It runs in its own thread, with its own

211

* event loop for receiving input events and doing other things.

212

*/

213

void android_main(struct android_app* state) {

214

struct engine engine;

215

216

// Make sure glue isn't stripped.

217

app_dummy();

218

219

memset(&engine, 0, sizeof(engine));

220

state->userData =

221

state->onAppCmd = engine_handle_cmd;

222

state->onInputEvent = engine_handle_input;

223

engine.app = state;

224

225

// Prepare to monitor accelerometer

226

engine.sensorManager = ASensorManager_getInstance();

227

engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager,

228

ASENSOR_TYPE_ACCELEROMETER);

229

engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager,

230

state->looper, LOOPER_ID_USER, NULL, NULL);

231

232

if (state->savedState != NULL) {

233

// We are starting with a previous saved state; restore from it.

234

engine.state = *(struct saved_state*)state->savedState;

235

}

236

237

// loop waiting for stuff to do.

238

239

while (1) {

240

// Read all pending events.

241

int ident;

242

int events;

243

struct android_poll_source* source;

244

245

// If not animating, we will block forever waiting for events.

246

// If animating, we loop until all events are read, then continue

247

// to draw the next frame of animation.

248

while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events,

249

(void**)&source)) >= 0) {

250

251

// Process this event.

252

if (source != NULL) {

253

source->process(state, source);

254

}

255

256

// If a sensor has data, process it now.

257

if (ident == LOOPER_ID_USER) {

258

if (engine.accelerometerSensor != NULL) {

259

ASensorEvent event;

260

while (ASensorEventQueue_getEvents(engine.sensorEventQueue,

261

&event, 1) > 0) {

262

LOGI("accelerometer: x=%f y=%f z=%f",

263

event.acceleration.x, event.acceleration.y,

264

event.acceleration.z);

265

}

266

}

267

}

268

269

// Check if we are exiting.

270

if (state->destroyRequested != 0) {

271

engine_term_display(&engine);

272

return;

273

}

274

}

275

276

if (engine.animating) {

277

// Done with events; draw next animation frame.

278

engine.state.angle += .01f;

279

if (engine.state.angle > 1) {

280

engine.state.angle = 0;

281

}

282

283

// Drawing is throttled to the screen update rate, so there

284

// is no need to do timing here.

285

engine_draw_frame(&engine);

286

}

287

}

288

}

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港