I show two approachs in the example:
- prepareBitmap_A:
- Create a array of int, fill in data point-by-point, then createBitmap from the array. - prepareBitmap_B:
- Create a bitmap, then fill in pixels by calling setPixel.
I also add code to display the (approximate) processing time in various steps for reference. The videos on the bottom show the result.
MySurfaceView.java
package com.example.androidsurfaceview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MySurfaceView extends SurfaceView {
private SurfaceHolder surfaceHolder;
private MyThread myThread;
MainActivity mainActivity;
long timeStart;
long timeA;
long timeB;
long timeFillBackground;
long timeDrawBitmap;
long timeTotal;
long numberOfPt;
public MySurfaceView(Context context) {
super(context);
init(context);
}
public MySurfaceView(Context context,
AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MySurfaceView(Context context,
AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context c){
mainActivity = (MainActivity)c;
numberOfPt = 0;
myThread = new MyThread(this);
surfaceHolder = getHolder();
surfaceHolder.addCallback(new SurfaceHolder.Callback(){
@Override
public void surfaceCreated(SurfaceHolder holder) {
myThread.setRunning(true);
myThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
myThread.setRunning(false);
while (retry) {
try {
myThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}});
}
private Bitmap prepareBitmap_A(int w, int h, long cnt){
int[] data = new int[w*h];
//fill with dummy data
for(int x=0; x<w; x++){
for(int y=0; y<h; y++){
//data[x + y*w] = 0xFF000000 + x;
if(cnt>=0){
data[x + y*w] = 0xFFff0000;
cnt--;
}else{
data[x + y*w] = 0xFFa0a0a0;
}
}
}
timeA = System.currentTimeMillis();
Bitmap bm = Bitmap.createBitmap(data, w, h, Bitmap.Config.ARGB_8888);
timeB = System.currentTimeMillis();
return bm;
}
private Bitmap prepareBitmap_B(int w, int h, long cnt){
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
timeA = System.currentTimeMillis();
//fill with dummy data
for(int x=0; x<w; x++){
for(int y=0; y<h; y++){
//data[x + y*w] = 0xFF000000 + x;
if(cnt>=0){
bm.setPixel(x, y, 0xFFff0000);
cnt--;
}else{
bm.setPixel(x, y, 0xFFa0a0a0);
}
}
}
timeB = System.currentTimeMillis();
return bm;
}
protected void drawSomething(Canvas canvas) {
numberOfPt += 500;
if(numberOfPt > (long)((getWidth()*getHeight()))){
numberOfPt = 0;
}
timeStart = System.currentTimeMillis();
Bitmap bmDummy = prepareBitmap_A(getWidth(), getHeight(), numberOfPt);
canvas.drawColor(Color.BLACK);
timeFillBackground = System.currentTimeMillis();
canvas.drawBitmap(bmDummy,
0, 0, null);
timeDrawBitmap = System.currentTimeMillis();
mainActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mainActivity.showDur(
timeA - timeStart,
timeB - timeA,
timeFillBackground - timeB,
timeDrawBitmap - timeFillBackground,
timeDrawBitmap - timeStart);
}
});
}
}
Modify activity_main.xml to add TextView to display processing time.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.androidsurfaceview.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://arteluzevida.blogspot.com/"
android:textStyle="bold" />
<TextView
android:id="@+id/durA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Duration: " />
<TextView
android:id="@+id/durB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Duration: " />
<TextView
android:id="@+id/durFillBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Duration: " />
<TextView
android:id="@+id/durDrawBM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Duration: " />
<TextView
android:id="@+id/durTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Duration: " />
<com.example.androidsurfaceview.MySurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.java
package com.example.androidsurfaceview;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView textDurA, textDurB, textDurFillBack,
textDurDrawBM, textDurTotal;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textDurA = (TextView)findViewById(R.id.durA);
textDurB = (TextView)findViewById(R.id.durB);
textDurFillBack = (TextView)findViewById(R.id.durFillBack);
textDurDrawBM = (TextView)findViewById(R.id.durDrawBM);
textDurTotal = (TextView)findViewById(R.id.durTotal);
}
protected void showDur(long dA, long dB, long dFill, long dDraw, long dTotal){
textDurA.setText("Duration(ms) - A: " + dA);
textDurB.setText("Duration(ms) - B: " + dB);
textDurFillBack.setText("Duration(ms) - Fill Background: " + dFill);
textDurDrawBM.setText("Duration(ms) - drawBitmap: " + dDraw);
textDurTotal.setText("Duration(ms) - Total: " + dTotal);
}
}
MyThread.java refer to last exercise, "Create animation on SurfaceView in background Thread".
Download the files.
prepareBitmap_A:
prepareBitmap_B: