1. 如何解决android系统的12个恼人问题
1. 系统速度逐渐变慢
当你购买了一款配置不俗的全新Android手机,一开始会觉得系统运行速度很流畅,但是随着时间的推移,系统会变得越来越慢,如果手机需要5秒钟才能打开网页浏览器,想必很多用户都会抓狂。幸运的是,你无需坐以待毙,也不用更换手机,只要下载安装一些支持自动定时清理的应用软件,就可以解决这个问题。
2. 无休止的通知提醒
Android系统的通知机制十分发达,甚至也被苹果iOS借鉴,但令人烦恼的是它总是在不停地发出通知内容,在一些特殊场合难免令人尴尬。你可以尝试在通知设置中手动关闭一些内容,但是无论关闭多少,总是会有新的服务通知蹦出来。所以,最有效的解决方法不是逐个手动关闭通知,而是选择一个无声的音频文件作为默认声音。
3. 无法摆脱的预装垃圾软件
与苹果iPhone几乎零预装的风格不同,大多数Android设备都预装了一些厂商自家服务或是运营商的定制服务,有些或许是精品,但大部分其实都是一些垃圾软件,你可能从来不会去使用它们。令人烦恼的是,一些内置应用无法卸载,并且在开机时自动驻留RAM中,影响整体性能。所以,你可以做的是在设置菜单中禁用这些应用,将它们“打入冷宫”。
4. 电池寿命较短
在理想的世界中,你可以使用手机上网、查看电子邮件、进行3D游戏,而电池电量没有丝毫减少;但残酷的现实是,如果你用一款Android手机进行以上操作,往往坚持不了一整天就需要充电。如果你愿意做出一些取舍,可以通过降低屏幕亮度、禁用背景数据和关闭GPS等操作,来延长电池寿命,而无需购买额外的电池或便携式充电器。如果不担心保修问题,你还可以通过Semaphore内核设置来降低手机的电压,来获得更长的续航能力。
5. 没有更精准的电量显示功能
大多数Android手机都没有提供精准的电量显示功能,所以你无法判断精准的剩余电量,从而控制使用强度。如果手机厂商没有为其配备电池百分比功能,你还可以通过下载第三方应用程序来实现这个功能。
6. 界面效果不美观
也许你是因为品牌、价格或是其他因素购买了一款Android手机,但并不喜欢它的界面效果,还可以通过安装第三方界面应用来进行美化,这是苹果iOS和微软Windows Phone都不支持的功能。Android领域的第三方界面软件十分丰富,比如GO桌面EX、国内MIUI等等,基本上都配备了个性化的主题,甚至是自定义的手势功能,一些界面软件的运行速度甚至要比原生更为流畅。
7. 获得其他Android手机的独家功能
俗话说,得不到的永远是最好的,有时候你可能会羡慕其他Android手机内置的一些独家功能,比如LG Optimus G Pro的QSLIDE多任务窗口、三星Galaxy S4的画中画视频播放或是摩托罗拉Droid RAZR的智能操作自动化服务等,其实你完全可以使用第三方应用来实现这些功能。比如在谷歌商店中搜索“浮动应用程序”,就可以找到“漂浮浏览器(Floating Browser Flux)”或是“超级视频(Super Video)”播放器,能够实现一定程度上的多任务操作功能;另外,类似“Tasker”这样的系统应用,只要设定一些条件,就可以实现手机自动化操作的功能。
8. “分享”菜单有太多选项
Android的最佳功能之一是其丰富的分享菜单功能,几乎列出了所有的可用内容,不过随着程序安装的增多,你会发现一些根本用不到的选项,看起来十分碍眼。第三方应用程序“Andmade”可以帮助你解决这个困扰,它可以重新自定义分享菜单,删除不必要的选项,并根据自己的需求进行重新排列。
9. 解锁界面太复杂
一些智能手机厂商开始在解锁界面上添加更多的内容,比如显示天气、最常用的应用程序甚至了社交应用的更新内容,但如果你只需要一个简单迅速的解锁界面,可以进入系统设置中更改解锁屏幕的显示信息。
10. 错误的系统默认应用
有时候你想打开Android手机中的一个文件,但却发现并不是你最希望使用的软件,这可能是一些应用程序更改了默认的打开方式。与Windows系统一样,你也可以自行设置系统打开相关文件的默认应用,只需要进入应用程序设置栏目中,清除应用程序的预设值,再次打开相同的文件时,系统就会弹出选项,让你选择默认应用,可以根据需求选择“始终”或是“仅一次”的操作形式。
11. 默认输入法太难用
通常情况下,Android手机的系统内置输入法都很糟糕,很难获得良好的使用体验。事实上我们依然可以通过下载第三方应用来改变这个情况,在谷歌应用商店中,可以找到一票类似的软件,比如QQ输入法,拥有更好的联想、手机键盘效果,也可自定义皮肤,更加符合国人的使用习惯。
12. 过时的Android系统版本
目前Android系统的最新版本是4.2果冻豆,但可能你的手机还是Android 4.0冰淇淋三明治、甚至是更过时的2.3版本。换句话说,你会错过一些最新的功能,比如谷歌语音助手、详细的通知内容以及所有适配新系统的应用程序。那么,除了祈祷手机厂商会在某一天内放出新版固件,你也可以尝试自行刷机。不过,刷机过程相对复杂一些,有可能会将设备刷成砖头,并且丧失保修服务。你可以参考一下XDA等专业论坛,一些ROM爱好者提供了相当丰富的自定义固件,并且附有详细的刷机条件和说明,只要按照步骤正确操作即可。对于已经ROOT过的机型,不仅可以刷自定义固件,甚至还可以超频,获得更流畅的使用体验。
2. Android为什么要用服务播放音乐不用子线程
1. 对于控制研究媒体播放器,通过本地服务打,不如送媒体播放器参考其他类一样CarefulMediaPlayer(MP,这一点);你在处理此类播放器的属性。我认为它帮助你。 谢谢 2. 我为这个问题挣扎,最后我得到了它的工作班以下。这个想法是一个线程与活套,剩下活着,并处理所有的MediaPlayer的逻辑。 我只退出尺蠖和清理线程,如果服务接收到的明确 public class PlayService extends IntentService { private static PowerManager.WakeLock wakeLock; private static final String TAG = "PlayService"; private static String LOCK_NAME = TAG; public static final String EXTRA_FILE = "file"; public static final String ACTION_PLAY = "play"; private static final String ACTION_STOP = "stop"; public static final int MSG_START = 1; public static final int MSG_STOP = 2; public PlayService(String name) { super(name); } public PlayService() { super("PlayService"); } @Override public void onCreate() { super.onCreate(); } @Override protected void onHandleIntent(Intent intent) { Message msg = new Message(); if (ACTION_PLAY.equalsIgnoreCase(intent.getAction())) { String fileName = intent.getExtras().getString(EXTRA_FILE); msg.what = MSG_START; msg.obj = fileName; } else if (ACTION_STOP.equalsIgnoreCase(intent.getAction())) { msg.what = MSG_STOP; } try { PlayMediaThread.getInstance(this).sendMessage(msg); } catch (InterruptedException e) { Log.e(TAG, e.getMessage()); } } public static PowerManager.WakeLock acquireLock(Context context) { if (wakeLock == null !wakeLock.isHeld()) { PowerManager powerManager = (PowerManager) context .getSystemService(Context.POWER_SERVICE); wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOCK_NAME); wakeLock.setReferenceCounted(true); wakeLock.acquire(); } return wakeLock; } public static void releaseLock(Context context) { if (wakeLock != null && wakeLock.isHeld()) { wakeLock.release(); } } } class PlayMediaThread extends Thread implements OnCompletionListener, OnErrorListener, OnPreparedListener { private static Semaphore semaphore = new Semaphore(0); private static Handler handler; private static Looper myLooper; private static Context context; private static String currentFileName; private static MediaPlayer player; private static PlayMediaThread instance; private static final String TAG = "PlayMediaThread"; private PlayMediaThread(Context context) throws InterruptedException { super(TAG); PlayMediaThread.context = context; start(); // To insure that the looper was initialized correctly before return an // instance semaphore.acquire(); } public static PlayMediaThread getInstance(Context context) throws InterruptedException { if (instance == null) { instance = new PlayMediaThread(context); } PlayMediaThread.context = context; return instance; } public void sendMessage(Message msg) { handler.sendMessage(msg); } public void quitLooper() { try { if (myLooper != null) { myLooper.quit(); Log.i(TAG, "After quit"); } } catch (Exception ex) { Log.e(TAG, ex.getMessage()); } } @Override public void run() { Looper.prepare(); myLooper = Looper.myLooper(); handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == PlayService.MSG_START) { startPlayer((String) msg.obj); } else if (msg.what == PlayService.MSG_STOP) { // when stop command is coming from the activity i.e. user // explicitly clicked stop, I quit the looper and // clean the thread stopPlayer(true); } } }; semaphore.release(); Log.i(TAG, "Before Loop"); Looper.loop(); } private void stopPlayer(boolean clean) { if (player != null) { if (player.isPlaying()) { player.stop(); } player.release(); player = null; } if (clean) { PlayService.releaseLock(context); quitLooper(); instance = null; } } private void startPlayer(String fileName) { if (player != null && player.isPlaying() && currentFileName != null && currentFileName.equalsIgnoreCase(fileName)) { return; } currentFileName = fileName; stopPlayer(false); player = new MediaPlayer(); player.setOnCompletionListener(this); player.setOnErrorListener(this); player.setOnPreparedListener(this); try { player.setDataSource(context, Uri.parse(currentFileName)); player.prepare(); player.start(); PlayService.acquireLock(context); } catch (Exception e) { Log.e(TAG, e.getMessage()); } } @Override public boolean onError(MediaPlayer mp, int arg1, int arg2) { Log.e(TAG, "onError"); stopPlayer(true); return false; } @Override public void onCompletion(MediaPlayer mp) { Log.d(TAG, "onCompletion"); // Just to quit the looper and clean the thread stopPlayer(true); } @Override public void onPrepared(MediaPlayer mp) { Log.d(TAG, "onPrepared"); } }
3. 安卓中的Binder架构是什么为什么要提供BinderService与Binder又有怎样的联系
建议您查找工具书,这么专业的只是怕是解决不了,抱歉,只能粗略的给您解释一下。Android 整体架构,不识庐山真面目,只缘身在此山中,所以我们先来大概看下 Android 这座大山的整体轮廓。我们先从 Android 的整体架构来看看 Binder 是处于什么地位,其实很简单,就是完成一个手机该有的核心功能如短信的收发管理、电话的接听、挂断以及应用程序的包管理、Activity 的管理等等。
Android 中“应用程序框架层”以 SDK 的形式开放给开发者使用,“系统服务层”中的核心服务随系统启动而运行,通过应用层序框架层提供的 Manager 实时为应用程序提供服务调用。系统服务层中每一个服务运行在自己独立的进程空间中,应用程序框架层中的 Manager 通过 Binder IPC 的方式调用系统服务层中的服务。Binder是Android系统进程间通信(IPC)方式之一 linux已经拥有的进程间通信IPC手段包括(Internet Process Connection)。
管道(Pipe)、信号(Signal)和跟踪(Trace)、插口(Socket)、报文队列(Message)、共享内存(Share Memory)和信号量(Semaphore)。本文详细介绍Binder作为Android主要IPC方式的优势。
4. Android上某应用唤醒另一应用的方式有多少种
进程中线程同步的四种常用方式:
1、 临界区(CCriticalSection)
当多个线程访问一个独占性共享资源时,可以使用临界区对象。拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,则被挂起,直到拥有临界区的线程放弃临界区为止。具体应用方式:
1、 定义临界区对象CcriticalSection g_CriticalSection;
2、 在访问共享资源(代码或变量)之前,先获得临界区对象,g_CriticalSection.Lock();
3、 访问共享资源后,则放弃临界区对象,g_CriticalSection.Unlock();
2、 事件(CEvent)
事件机制,则允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。比如在某些网络应用程序中,一个线程如A负责侦听通信端口,另外一个线程B负责更新用户数据,利用事件机制,则线程A可以通知线程B何时更新用户数据。每个Cevent对象可以有两种状态:有信号状态和无信号状态。Cevent类对象有两种类型:人工事件和自动事件。
自动事件对象,在被至少一个线程释放后自动返回到无信号状态;
人工事件对象,获得信号后,释放可利用线程,但直到调用成员函数ReSet()才将其设置为无信号状态。在创建Cevent对象时,默认创建的是自动事件。
1、1234CEvent(BOOL bInitiallyOwn=FALSE, BOOL bManualReset=FALSE, LPCTSTR lpszName=NULL, LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);
bInitiallyOwn:指定事件对象初始化状态,TRUE为有信号,FALSE为无信号;
bManualReset:指定要创建的事件是属于人工事件还是自动事件。TRUE为人工事件,FALSE为自动事件;
后两个参数一般设为NULL,在此不作过多说明。
2、BOOL CEvent::SetEvent();
将Cevent类对象的状态设置为有信号状态。如果事件是人工事件,则Cevent类对象保持为有信号状态,直到调用成员函数ResetEvent()将其重新设为无信号状态时为止。如果为自动事件,则在SetEvent()后将事件设置为有信号状态,由系统自动重置为无信号状态。
3、BOOL CEvent::ResetEvent();
将事件的状态设置为无信号状态,并保持该状态直至SetEvent()被调用为止。由于自动事件是由系统自动重置,故自动事件不需要调用该函数。
一般通过调用WaitForSingleObject()函数来监视事件状态。
3、 互斥量(CMutex)
互斥对象和临界区对象非常相似,只是其允许在进程间使用,而临界区只限制与同一进程的各个线程之间使用,
但是更节省资源,更有效率。
4、 信号量(CSemphore)
当需要一个计数器来限制可以使用某共享资源的线程数目时,可以使用“信号量”对象。CSemaphore类对象保存了对当前访问某一个指定资源的线程的计数值,该计数值是当前还可以使用该资源的线程数目。如果这个计数达到了零,则所有对这个CSemaphore类对象所控制的资源的访问尝试都被放入到一个队列中等待,直到超时或计数值不为零为止。
CSemaphore(
LONG lInitialCount = 1,
LONG lMaxCount = 1,
LPCTSTR pstrName = NULL,
LPSECURITY_ATTRIBUTES lpsaAttributes = NULL
);
lInitialCount:信号量对象的初始计数值,即可访问线程数目的初始值;
lMaxCount:信号量对象计数值的最大值,该参数决定了同一时刻可访问由信号量保护的资源的线程最大数目;
后两个参数在同一进程中使用一般为NULL,不作过多讨论;
一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就减1,只要当前可用资源计数大于0,就可以发出信号量信号。如果为0,则放入一个队列中等待。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可用资源数加1。
BOOL ReleaseSemaphore( HANDLE hSemaphore, // hSemaphore:信号量句柄
LONG lReleaseCount, // lReleaseCount:信号量计数值
LPLONG lpPreviousCount // 参数一般为NULL);
5. android里音乐没播放怎么也调用setoncompletionlistener
1.对于控制研究媒体播放器,通过本地服务打,不如送媒体播放器参考其他类一样CarefulMediaPlayer(MP,这一点);你在处理此类播放器的属性。我认为它帮助你。 谢谢
2.我为这个问题挣扎,最后我得到了它的工作班以下。这个想法是一个线程与活套,剩下活着,并处理所有的MediaPlayer的逻辑。 我只退出尺蠖和清理线程,如果服务接收到的明确
java">{
privatestaticPowerManager.WakeLockwakeLock;
privatestaticfinalStringTAG="PlayService";
privatestaticStringLOCK_NAME=TAG;
publicstaticfinalStringEXTRA_FILE="file";
publicstaticfinalStringACTION_PLAY="play";
_STOP="stop";
publicstaticfinalintMSG_START=1;
publicstaticfinalintMSG_STOP=2;
publicPlayService(Stringname){
super(name);
}
publicPlayService(){
super("PlayService");
}
@Override
publicvoidonCreate(){
super.onCreate();
}
@Override
protectedvoidonHandleIntent(Intentintent){
Messagemsg=newMessage();
if(ACTION_PLAY.equalsIgnoreCase(intent.getAction())){
StringfileName=intent.getExtras().getString(EXTRA_FILE);
msg.what=MSG_START;
msg.obj=fileName;
}elseif(ACTION_STOP.equalsIgnoreCase(intent.getAction())){
msg.what=MSG_STOP;
}
try{
PlayMediaThread.getInstance(this).sendMessage(msg);
}catch(InterruptedExceptione){
Log.e(TAG,e.getMessage());
}
}
publicstaticPowerManager.WakeLockacquireLock(Contextcontext){
if(wakeLock==null||!wakeLock.isHeld()){
PowerManagerpowerManager=(PowerManager)context
.getSystemService(Context.POWER_SERVICE);
wakeLock=powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
LOCK_NAME);
wakeLock.setReferenceCounted(true);
wakeLock.acquire();
}
returnwakeLock;
}
publicstaticvoidreleaseLock(Contextcontext){
if(wakeLock!=null&&wakeLock.isHeld()){
wakeLock.release();
}
}
}
,
OnErrorListener,OnPreparedListener{
=newSemaphore(0);
privatestaticHandlerhandler;
privatestaticLoopermyLooper;
privatestaticContextcontext;
;
;
;
privatestaticfinalStringTAG="PlayMediaThread";
privatePlayMediaThread(Contextcontext)throwsInterruptedException{
super(TAG);
PlayMediaThread.context=context;
start();
//
//instance
semaphore.acquire();
}
(Contextcontext)
throwsInterruptedException{
if(instance==null){
instance=newPlayMediaThread(context);
}
PlayMediaThread.context=context;
returninstance;
}
publicvoidsendMessage(Messagemsg){
handler.sendMessage(msg);
}
publicvoidquitLooper(){
try{
if(myLooper!=null){
myLooper.quit();
Log.i(TAG,"Afterquit");
}
}catch(Exceptionex){
Log.e(TAG,ex.getMessage());
}
}
@Override
publicvoidrun(){
Looper.prepare();
myLooper=Looper.myLooper();
handler=newHandler(){
@Override
publicvoidhandleMessage(Messagemsg){
if(msg.what==PlayService.MSG_START){
startPlayer((String)msg.obj);
}elseif(msg.what==PlayService.MSG_STOP){
//.e.user
//explicitlyclickedstop,Iquitthelooperand
//cleanthethread
stopPlayer(true);
}
}
};
semaphore.release();
Log.i(TAG,"BeforeLoop");
Looper.loop();
}
privatevoidstopPlayer(booleanclean){
if(player!=null){
if(player.isPlaying()){
player.stop();
}
player.release();
player=null;
}
if(clean){
PlayService.releaseLock(context);
quitLooper();
instance=null;
}
}
privatevoidstartPlayer(StringfileName){
if(player!=null&&player.isPlaying()&¤tFileName!=null
&¤tFileName.equalsIgnoreCase(fileName)){
return;
}
currentFileName=fileName;
stopPlayer(false);
player=newMediaPlayer();
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
player.setOnPreparedListener(this);
try{
player.setDataSource(context,Uri.parse(currentFileName));
player.prepare();
player.start();
PlayService.acquireLock(context);
}catch(Exceptione){
Log.e(TAG,e.getMessage());
}
}
@Override
publicbooleanonError(MediaPlayermp,intarg1,intarg2){
Log.e(TAG,"onError");
stopPlayer(true);
returnfalse;
}
@Override
publicvoidonCompletion(MediaPlayermp){
Log.d(TAG,"onCompletion");
//
stopPlayer(true);
}
@Override
publicvoidonPrepared(MediaPlayermp){
Log.d(TAG,"onPrepared");
}
}
6. 毕业设计选了用android做一个3d魔方的游戏,应为android以前没接触过的,要从头开始学的。这个难吗高手
只要java好就没有问题,这是3D魔方android的源码。
package com.example.android.image3D;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.content.Context;
import android.util.AttributeSet;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL;
import javax.microedition.khronos.opengles.GL10;
public class View3D extends SurfaceView implements SurfaceHolder.Callback {
private static final Semaphore sEglSemaphore = new Semaphore(1);
private boolean mSizeChanged = true;
private SurfaceHolder mHolder;
private GLThread mGLThread;
private GLWrapper mGLWrapper;
public View3D(Context context) {
super(context);
init();
}
public View3D(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
}
public SurfaceHolder getSurfaceHolder() {
return mHolder;
}
public void setGLWrapper(GLWrapper glWrapper) {
mGLWrapper = glWrapper;
}
public void setRenderer(Renderer renderer) {
mGLThread = new GLThread(renderer);
mGLThread.start();
}
public void surfaceCreated(SurfaceHolder holder) {
mGLThread.surfaceCreated();
}
public void surfaceDestroyed(SurfaceHolder holder) {
mGLThread.surfaceDestroyed();
}
public void surfaceChanged(SurfaceHolder holder,
int format, int w, int h) {
mGLThread.onWindowResize(w, h);
}
public void onPause() {
mGLThread.onPause();
}
public void onResume() {
mGLThread.onResume();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
mGLThread.onWindowFocusChanged(hasFocus);
}
public void queueEvent(Runnable r) {
mGLThread.queueEvent(r);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mGLThread.requestExitAndWait();
}
public interface GLWrapper {
GL wrap(GL gl);
}
public interface Renderer {
int[] getConfigSpec();
void surfaceCreated(GL10 gl);
void sizeChanged(GL10 gl, int width, int height);
void drawFrame(GL10 gl);
}
private class EglHelper {
EGL10 mEgl;
EGLDisplay mEglDisplay;
EGLSurface mEglSurface;
EGLConfig mEglConfig;
EGLContext mEglContext;
public EglHelper() {
}
public void start(int[] configSpec){
mEgl = (EGL10) EGLContext.getEGL();
mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
int[] version = new int[2];
mEgl.eglInitialize(mEglDisplay, version);
EGLConfig[] configs = new EGLConfig[1];
int[] num_config = new int[1];
mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1,
num_config);
mEglConfig = configs[0];
mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig,
EGL10.EGL_NO_CONTEXT, null);
mEglSurface = null;
}
public GL createSurface(SurfaceHolder holder) {
if (mEglSurface != null) {
mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
}
mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay,
mEglConfig, holder, null);
mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
mEglContext);
GL gl = mEglContext.getGL();
if (mGLWrapper != null) {
gl = mGLWrapper.wrap(gl);
}
return gl;
}
public boolean swap() {
mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
return mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST;
}
public void finish() {
if (mEglSurface != null) {
mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_CONTEXT);
mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
mEglSurface = null;
}
if (mEglContext != null) {
mEgl.eglDestroyContext(mEglDisplay, mEglContext);
mEglContext = null;
}
if (mEglDisplay != null) {
mEgl.eglTerminate(mEglDisplay);
mEglDisplay = null;
}
}
}
class GLThread extends Thread {
private boolean mDone;
private boolean mPaused;
private boolean mHasFocus;
private boolean mHasSurface;
private boolean mContextLost;
private int mWidth;
private int mHeight;
private Renderer mRenderer;
private ArrayList<Runnable>
mEventQueue = new ArrayList<Runnable>();
private EglHelper mEglHelper;
GLThread(Renderer renderer) {
super();
mDone = false;
mWidth = 0;
mHeight = 0;
mRenderer = renderer;
setName("GLThread");
}
@Override
public void run() {
try {
try {
sEglSemaphore.acquire();
} catch (InterruptedException e) {
return;
}
guardedRun();
} catch (InterruptedException e) {
} finally {
sEglSemaphore.release();
}
}
private void guardedRun() throws InterruptedException {
mEglHelper = new EglHelper();
int[] configSpec = mRenderer.getConfigSpec();
mEglHelper.start(configSpec);
GL10 gl = null;
boolean tellRendererSurfaceCreated = true;
boolean tellRendererSurfaceChanged = true;
while (!mDone) {
int w, h;
boolean changed;
boolean needStart = false;
synchronized (this) {
Runnable r;
while ((r = getEvent()) != null) {
r.run();
}
if (mPaused) {
mEglHelper.finish();
needStart = true;
}
if(needToWait()) {
while (needToWait()) {
wait();
}
}
if (mDone) {
break;
}
changed = mSizeChanged;
w = mWidth;
h = mHeight;
mSizeChanged = false;
}
if (needStart) {
mEglHelper.start(configSpec);
tellRendererSurfaceCreated = true;
changed = true;
}
if (changed) {
gl = (GL10) mEglHelper.createSurface(mHolder);
tellRendererSurfaceChanged = true;
}
if (tellRendererSurfaceCreated) {
mRenderer.surfaceCreated(gl);
tellRendererSurfaceCreated = false;
}
if (tellRendererSurfaceChanged) {
mRenderer.sizeChanged(gl, w, h);
tellRendererSurfaceChanged = false;
}
if ((w > 0) && (h > 0)) {
mRenderer.drawFrame(gl);
mEglHelper.swap();
}
}
mEglHelper.finish();
}
private boolean needToWait() {
return (mPaused || (! mHasFocus) || (! mHasSurface) || mContextLost)
&& (! mDone);
}
public void surfaceCreated() {
synchronized(this) {
mHasSurface = true;
mContextLost = false;
notify();
}
}
public void surfaceDestroyed() {
synchronized(this) {
mHasSurface = false;
notify();
}
}
public void onPause() {
synchronized (this) {
mPaused = true;
}
}
public void onResume() {
synchronized (this) {
mPaused = false;
notify();
}
}
public void onWindowFocusChanged(boolean hasFocus) {
synchronized (this) {
mHasFocus = hasFocus;
if (mHasFocus == true) {
notify();
}
}
}
public void onWindowResize(int w, int h) {
synchronized (this) {
mWidth = w;
mHeight = h;
mSizeChanged = true;
}
}
public void requestExitAndWait() {
synchronized(this) {
mDone = true;
notify();
}
try {
join();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
public void queueEvent(Runnable r) {
synchronized(this) {
mEventQueue.add(r);
}
}
private Runnable getEvent() {
synchronized(this) {
if (mEventQueue.size() > 0) {
return mEventQueue.remove(0);
}
}
return null;
}
}
}
7. 浅谈linux进程之间是如何通信的
有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点;【java培训】 2、管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信; 3、套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字;【学习java】 4、信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数); 5、共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥;【java学习】 6、信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。 以上就是linux操作系统下进程之间的通信讲解,希望对广大学习者有所帮助。 腾科IT教育软件学院是腾科IT教育集团旗下的全资子公司,是一家专业从事Java, Android, Oracle Java, Linux Java, 系统架构师等高端IT技能培训的专业机构。也是甲骨文授权的广州唯一一家正版Oracle Java学习中心!秉承六年办学理念,致力于提供全球领先的培训方案,着力打造IT行业精英人才。学校位于广州最繁华的金融商业中心天河区,地理位置优越,学校环境优美,教学设施完备,师资力量雄厚。