我正在开发一款安卓游戏,我正在使用SurfaceView.我有一个方法,每16ms调用一次(我希望有60fps)
public void myDraw(SurfaceHolder holder) {
Canvas c = null;
long start = System.currentMillis();
try {
synchronized(holder) {
c = holder.lockCanvas();
if (c != null) {
c.drawColor(Color.GREEN);
}
}
} finally {
if (c != null) {
holder.unlockCanvas(c);
}
}
Log.i(TAG, "total time:" + (System.currentMillis() - start));
}
Run Code Online (Sandbox Code Playgroud)
当我运行我的应用程序时,LogCat的输出是:
total time:30
total time:23
total time:6
total time:39
total time:17
Run Code Online (Sandbox Code Playgroud)
为什么锁定/解锁画布需要花费太多时间?有没有更好的方法解决我的问题?(也就是说,有一个60 fps的应用程序)
谢谢!
我正在尝试为Android应用程序创建2D游戏引擎.我已经按照本教程,它可以很好地创建一个全屏显示,但我不希望这样.我想让我的视图占据屏幕的前2/3(或其他),并使用标准的Android小部件(按钮,文本输入等)填充底部的第三个.我不能让这个工作.我能得到的最好的是一个空白的白色屏幕.我尝试了很多排列,包括使用外部LinerLayout,然后将自定义SurfaceView嵌入到嵌套的RelativeLayout中,并将Android小部件放在嵌套的LinearLayout中,它不起作用.
例如,当我觉得它应该是50%SurfaceView时,这会产生一个白色屏幕,对于TextView,它会产生50%:
activity_main.xml中:
<LinearLayout 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:baselineAligned="false" >
<RelativeLayout
android:layout_width="0dip"
android:layout_height="0dp"
android:layout_weight="1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapContainer"
>
</RelativeLayout>
<LinearLayout
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="0dp"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/white"
android:text="@string/test_str" />
</LinearLayout>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
MainActivity.java:
package com.removed.for.privacy;
import com.removed.for.privacy;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout mapContainer = (RelativeLayout) findViewById(R.id.mapContainer);
JSMapView mapView = new JSMapView(this);
mapContainer.addView(mapView);
}
@Override
public boolean …Run Code Online (Sandbox Code Playgroud) 我有2个独立的Android应用程序(apk)。
应用1 SurfaceView在其中创建,并应为其他应用提供AIDL方法,以获取SurfaceHolderfor 的实例SurfaceView。因此,其他应用程序将能够在该视图中绘制,该视图显示在应用程序编号1中。
Surface由于它实现了Parcelable接口,因此我可以轻松地通过aidl 进行自身传输。
// IMainService.aidl
package com.commonsware.cwac.preso.demo.service;
import android.view.Surface;
interface IMainService {
Surface getSurf();
}
Run Code Online (Sandbox Code Playgroud)
但是第三方SDK需要SurfaceHolder使用。所以问题是-我如何SurfaceHolder为给定Surface实例创建,或者如何SurfaceHolder通过AIDL进行传输。有什么例子可以实现Parcelable SurfaceHolder吗?
我的用例(如果有的话):应用程序1作为a启动,Service并在Presentation Screen上绘制UI。而且,我需要一种方法来让另一个应用程序通过应用程序1内的Nokia Here Mobile SDK显示导航数据。我需要SurfaceHolder使用此 api。
任何帮助将不胜感激。
我正在尝试在运行相机预览的表面上显示图像.到目前为止,我使用SurfaceHolder运行相机.我想也许我可以使用FrameLayout将图像堆叠在相机预览的顶部,但我不知道如何去做.我怎么能这样做,还是有其他方法可以做到这一点?
我更喜欢以编程方式编写代码,但感谢任何帮助!
谢谢
我正在开发一个自定义相机应用程序.下面是我的Activity类.
public class MyCustomCam extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mCamera = getCameraInstance();
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist) …Run Code Online (Sandbox Code Playgroud) 所以我设置了这个相机预览Camera,SurfaceView和SurfaceHolder.我还有一个ImageView地方,我将把相机图像的修改版本,我希望这更新让我们说每秒一次.
当我从"res"加载图像时,所有代码都准备好并且已经工作但是我很难从相机读取图像数据.
我已经尝试过了:
创建一个intentfor MediaStore.ACTION_IMAGE_CAPTURE并开始onActivityResult获取一个小缩略图(实际上足够我)(Bitmap)data.getExtras().get("data")
问题是这会打开相机应用程序,你需要"手动"拍照.
使用创建Camera.PreviewCallback,拍摄YuvImage并将其转换为图像YuvImage.compressToJpeg(...).
这里的问题是无论何时何地我都无法启动它 Camera.setPreviewCallbackWithBuffer(PreviewCallback).
PreviewHolder通过锁定到画布直接获取数据lockCanvas()并尝试将其转换为位图编辑: 这项工作的最佳方法是什么?我的意思是QR码阅读器必须不断地从相机中读取图像数据,它们如何工作?
用什么代替surfaceholder.settype?
PreviewHolder = CameraPreview.getHolder();
PreviewHolder.addCallback(this);
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
PreviewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Run Code Online (Sandbox Code Playgroud) 我在网上浮动的许多例子都有类似的代码:
mSurfaceHolder = mVideoSurface.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setFormat(PixelFormat.TRANSPARENT);
mSurfaceHolder.setFixedSize(20, 10);
Run Code Online (Sandbox Code Playgroud)
然后在回调中我有:
@Override public void surfaceCreated(SurfaceHolder holder)
{
Log.d(TAG, "SurfaceCreated");
mSurfaceHolder.setFixedSize(20, 10);
}
@Override public void surfaceChanged(
SurfaceHolder holder, int format, int width, int height
)
{
Log.d(TAG, "SurfaceChanged to " +
format + " width " + width + " height " + height);
}
Run Code Online (Sandbox Code Playgroud)
从这段代码中我可以预期视频表面被设置为20x10像素的微小尺寸,然后缩小到我正在使用它的任何布局尺寸,显示像素化/模糊版本.但是,正在播放的视频在其完整的原始分辨率下看起来是正确的,它不会缩小到20x10.但我得到这样的日志:
SurfaceChanged to -2 width 20 height 10
Run Code Online (Sandbox Code Playgroud)
因此,如果视频表面设置为这么小的尺寸,但从图形上看,视频看起来仍然是高清晰度,设置表面尺寸有什么用?
在我的活动中,我有一些观点和一个surfaceView.
这是我的第一个代码 onCreate()
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
upBtn = (Button) findViewById(R.id.upBtn);
// and more widget here
surface = (SurfaceView) findViewById(R.id.surfaceView);
this.holder = surface.getHolder(); // NullPointerException
setContentView(R.layout.view);
Run Code Online (Sandbox Code Playgroud)
如果我通过take surfaceView和getHolder()in 更改上面的代码onResume()(我已经多次尝试过这个结果),没有错误:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
upBtn = (Button) findViewById(R.id.upBtn);
// and more widget here
// surface = (SurfaceView) findViewById(R.id.surfaceView); //cancel
// this.holder = surface.getHolder(); // cancel
setContentView(R.layout.view);
Run Code Online (Sandbox Code Playgroud)
public void onResume() {
surface = (SurfaceView) findViewById(R.id.surfaceView);
this.holder = surface.getHolder(); // No Error …Run Code Online (Sandbox Code Playgroud) 我使用 SurfaceView 在屏幕上移动两个位图图片。我试过这个:
...
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
...
canvas.drawBitmap(bitmap,matrix,paint);
canvas.drawBitmap(bitmap2,matrix,paint);
}
...
Run Code Online (Sandbox Code Playgroud)
如何像这样将画布保存到 sdCard 中?
public saveCanvasIntoSdCard(Canvas canvas)
{
}
Run Code Online (Sandbox Code Playgroud) android surfaceview surfaceholder android-canvas android-bitmap
我已经搜索了这个问题两天了.我知道这是由一些愚蠢的错误引起的,但我无法找到那个东西.如果有人帮助我,那会很棒.这是片段
private void draw() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = holder.lockCanvas();;
try {
update(c);
updateText(c); //These are the effects like snowing or bouncing
} finally {
if (c != null)
holder.unlockCanvasAndPost(c); //This is line no. 151
}
mHandler.removeCallbacks(drawRunner);
if (mVisible) {
mHandler.postDelayed(drawRunner, 10);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为问题在于上述方法.这是logcat:
11-18 11:29:15.145: E/AndroidRuntime(2845): java.lang.IllegalArgumentException
11-18 11:29:15.145: E/AndroidRuntime(2845): at android.view.Surface.unlockCanvasAndPost(Native Method)
11-18 11:29:15.145: E/AndroidRuntime(2845): at com.android.internal.view.BaseSurfaceHolder.unlockCanvasAndPost(BaseSurfaceHolder.java:215)
11-18 11:29:15.145: E/AndroidRuntime(2845): at com.example.livewallpaper.SnowEffect$MyBounce.draw(SnowEffect.java:151)
11-18 11:29:15.145: E/AndroidRuntime(2845): at com.example.livewallpaper.SnowEffect$MyBounce.access$0(SnowEffect.java:141)
11-18 11:29:15.145: E/AndroidRuntime(2845): at com.example.livewallpaper.SnowEffect$MyBounce$1.run(SnowEffect.java:55)
Run Code Online (Sandbox Code Playgroud)