當前位置:首頁 » 安卓系統 » android自定義回調

android自定義回調

發布時間: 2022-06-27 05:47:59

⑴ android 回調方法怎麼寫

package com.smart;
/**
* 定義回調介面
*/
public interface CallBack {
void execute();
}

package com.smart;
/**
* 工具類
*/
public class Tools {
public void test(CallBack callBack){
long begin = System.currentTimeMillis(); //測試起始時間
callBack.execute();///進行回調操作
long end = System.currentTimeMillis(); //測試結束時間
System.out.println("[use time]:" + (end - begin)); //列印使用時間

}
public static void main(String[] args){
Tools tools = new Tools();
tools.test(new CallBack(){
public void execute() {
//A.method(); 測試類A的某個方法執行的時間
//B.method(); 測試類B的某個方式執行的時間
System.out.print("回調" );
}
});
}
}
package com.smart;
/**
* 工具類
*/
public class Tools {
public void test(CallBack callBack){
long begin = System.currentTimeMillis();//測試起始時間
callBack.execute();///進行回調操作
long end = System.currentTimeMillis();//測試結束時間
System.out.println("[use time]:" + (end - begin));//列印使用時間

}
public static void main(String[] args){
Tools tools = new Tools();
tools.test(new CallBack(){
public void execute() {
//A.method(); 測試類A的某個方法執行的時間
//B.method(); 測試類B的某個方式執行的時間
System.out.print("回調");
}
});
}
}

⑵ Android 自定義控制項中實現介面回調時為什麼影響界面繪線

SurfaceView是View的子類,它內嵌了一個專門用於繪制的Surface,你可以控制這個Surface的格式和尺寸,Surfaceview控制這個Surface的繪制位置。surface是縱深排序(Z-ordered)的,說明它總在自己所在窗口的後面。SurfaceView提供了一個可見區域,只有在這個可見區域內的surface內容才可見。surface的排版顯示受到視圖層級關系的影響,它的兄弟視圖結點會在頂端顯示。這意味者 surface的內容會被它的兄弟視圖遮擋,這一特性可以用來放置遮蓋物(overlays)(例如,文本和按鈕等控制項)。注意,如果surface上面有透明控制項,那麼每次surface變化都會引起框架重新計算它和頂層控制項的透明效果,這會影響性能。
SurfaceView默認使用雙緩沖技術的,它支持在子線程中繪制圖像,這樣就不會阻塞主線程了,所以它更適合於游戲的開發。

SurfaceView的使用
首先繼承SurfaceView,並實現SurfaceHolder.Callback介面,實現它的三個方法:surfaceCreated,surfaceChanged,surfaceDestroyed。
surfaceCreated(SurfaceHolder holder):surface創建的時候調用,一般在該方法中啟動繪圖的線程。
surfaceChanged(SurfaceHolder holder, int format, int width,int height):surface尺寸發生改變的時候調用,如橫豎屏切換。
surfaceDestroyed(SurfaceHolder holder) :surface被銷毀的時候調用,如退出遊戲畫面,一般在該方法中停止繪圖線程。
還需要獲得SurfaceHolder,並添加回調函數,這樣這三個方法才會執行。

SurfaceView實戰
下面通過一個小demo來學習SurfaceView在實際項目中的使用,繪制一個精靈,該精靈有四個方向的行走動畫,讓精靈沿著屏幕四周不停的行走。

⑶ 如何在android的jni線程中實現回調

JNI回調是指在c/c++代碼中調用java函數,當在c/c++的線程中執行回調函數時,會導致回調失敗。 其中一種在Android系統的解決方案是: 把c/c++中所有線程的創建,由pthread_create函數替換為由Java層的創建線程的函數AndroidRuntime::createJavaThread。 假設有c++函數: [cpp] view plain void *thread_entry(void *args) { while(1) { printf("thread running...\n"); sleep(1); } } void init() { pthread_t thread; pthread_create(&thread,NULL,thread_entry,(void *)NULL); } init()函數創建一個線程,需要在該線程中調用java類Test的回調函數Receive: [cpp] view plain public void Receive(char buffer[],int length){ String msg = new String(buffer); msg = "received from jni callback:" + msg; Log.d("Test", msg); } 首先在c++中定義回調函數指針: [cpp] view plain //test.h #include <pthread.h> //function type for receiving data from native typedef void (*ReceiveCallback)(unsigned char *buf, int len); /** Callback for creating a thread that can call into the Java framework code. * This must be used to create any threads that report events up to the framework. */ typedef pthread_t (* CreateThreadCallback)(const char* name, void (*start)(void *), void* arg); typedef struct{ ReceiveCallback recv_cb; CreateThreadCallback create_thread_cb; }Callback; 再修改c++中的init和thread_entry函數: [cpp] view plain //test.c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <sys/wait.h> #include <unistd.h> #include "test.h" void *thread_entry(void *args) { char *str = "i'm happy now"; Callback cb = NULL; int len; if(args != NULL){ cb = (Callback *)args; } len = strlen(str); while(1) { printf("thread running...\n"); //invoke callback method to java if(cb != NULL && cb->recv_cb != NULL){ cb->recv_cb((unsigned char*)str, len); } sleep(1); } } void init(Callback *cb) { pthread_t thread; //pthread_create(&thread,NULL,thread_entry,(void *)NULL); if(cb != NULL && cb->create_thread_cb != NULL) { cb->create_thread_cb("thread",thread_entry,(void *)cb); } } 然後在jni中實現回調函數,以及其他實現: [cpp] view plain //jni_test.c #include <stdlib.h> #include <malloc.h> #include <jni.h> #include <JNIHelp.h> #include "android_runtime/AndroidRuntime.h" #include "test.h" #define RADIO_PROVIDER_CLASS_NAME "com/tonny/Test" using namespace android; static jobject mCallbacksObj = NULL; static jmethodID method_receive; static void (JNIEnv* env, const char* methodName) { if (env->ExceptionCheck()) { LOGE("An exception was thrown by callback '%s'.", methodName); LOGE_EX(env); env->ExceptionClear(); } } static void receive_callback(unsigned char *buf, int len) { int i; JNIEnv* env = AndroidRuntime::getJNIEnv(); jcharArray array = env->NewCharArray(len); jchar *pArray ; if(array == NULL){ LOGE("receive_callback: NewCharArray error."); return; } pArray = (jchar*)calloc(len, sizeof(jchar)); if(pArray == NULL){ LOGE("receive_callback: calloc error."); return; } // buffer to jchar array for(i = 0; i < len; i++) { *(pArray + i) = *(buf + i); } // buffer to jcharArray env->SetCharArrayRegion(array,0,len,pArray); //invoke java callback method env->CallVoidMethod(mCallbacksObj, method_receive,array,len); //release resource env->DeleteLocalRef(array); free(pArray); pArray = NULL; (env, __FUNCTION__); } static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg) { return (pthread_t)AndroidRuntime::createJavaThread(name, start, arg); } static Callback mCallbacks = { receive_callback, create_thread_callback }; static void jni_class_init_native (JNIEnv* env, jclass clazz) { method_receive = env->GetMethodID(clazz, "Receive", "([CI)V"); } static int jni_init (JNIEnv *env, jobject obj) { if (!mCallbacksObj) mCallbacksObj = env->NewGlobalRef(obj); return init(&mCallbacks); } static const JNINativeMethod gMethods[] = { { "class_init_native", "()V", (void *)jni_class_init_native }, { "native_init", "()I", (void *)jni_init }, }; static int registerMethods(JNIEnv* env) { const char* const kClassName = RADIO_PROVIDER_CLASS_NAME; jclass clazz; /* look up the class */ clazz = env->FindClass(kClassName); if (clazz == NULL) { LOGE("Can't find class %s/n", kClassName); return -1; } /* register all the methods */ if (env->RegisterNatives(clazz,gMethods,sizeof(gMethods)/sizeof(gMethods[0])) != JNI_OK) { LOGE("Failed registering methods for %s/n", kClassName); return -1; } /* fill out the rest of the ID cache */ return 0; } jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = -1; LOGI("Radio JNI_OnLoad"); if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { LOGE("ERROR: GetEnv failed/n"); goto fail; } if(env == NULL){ goto fail; } if (registerMethods(env) != 0) { LOGE("ERROR: PlatformLibrary native registration failed/n"); goto fail; } /* success -- return valid version number */ result = JNI_VERSION_1_4; fail: return result; } jni的Android.mk文件中共享庫設置為: [cpp] view plain LOCAL_SHARED_LIBRARIES := liblog libcutils libandroid_runtime libnativehelper 最後再實現Java中的Test類: [java] view plain //com.tonny.Test.java public class Test { static{ try { System.loadLibrary("test"); class_init_native(); } catch(UnsatisfiedLinkError ule){ System.err.println("WARNING: Could not load library libtest.so!"); } } public int initialize() { return native_radio_init(); } public void Receive(char buffer[],int length){ String msg = new String(buffer); msg = "received from jni callback" + msg; Log.d("Test", msg); } protected static native void class_init_native(); protected native int native_init(); }

⑷ android介面回調的幾種

可以使用Observer,觀察者模式來實現回調。或者介面中傳入類,然後在介面處理之後,進行調用類的方法進行回調。
介面回調示例
public interface ConfirmDialogListener{
public void onLeft(Object obj); //按確認鍵
public void onRight(Object obj);//按back鍵
}
public static Dialog confirmDialog(final Context activity, final ConfirmDialogListener listener,final Object obj){

if(listener != null)
listener.onRight(obj);
}

⑸ android中回調函數是怎麼調用的

CallBack是回調的意思,一般稱之為回調函數
網路的解釋:http://ke..com/link?url=8yMUwVEFRzxR4JGMxVN_
用一個比較形象的例子:
你餓了,想吃飯,就一會去問你媽一聲"開飯沒有啊?"
這就是正常函數調用.
但是今天你媽包餃子,花的時間比較長,你跑啊跑啊,就煩了.於是你給你媽說,我先出去玩會,開飯的時候打我手機.
等過了一陣,你媽給你打電話說"開飯啦,回來吃飯吧!"
其中,你告訴你媽打手機找你,就是你把回調函數句柄保存到你媽的動作.你媽打

⑹ android定義在抽象方法中的回調函數有哪些

提示:在閱讀本文章之前,請確保您對Touch事件的分發機制有一定的了解
在Android的學習過程中經常會聽到或者見到「回調」這個詞,那麼什麼是回調呢?所謂的回調函數就是:在A類中定義了一個方法,這個方法中用到了一個介面和該介面中的抽象方法,但是抽象方法沒有具體的實現,需要B類去實現,B類實現該方法後,它本身不會去調用該方法,而是傳遞給A類,供A類去調用,這種機制就稱為回調。
下面我們拿具體的Button的點擊事件進行模擬分析:
首先,在View類中我們能找到setOnClickListener(OnClickListener l)方法:

⑺ Android 回調介面是啥,回調機制詳解

在Android中到處可見介面回調機制,尤其是UI事件處理方面,這里介紹android介面回調機制,涉及到android介面回調相關知識

在使用介面回調的時候發現了一個經常犯的錯誤,就是回調函數裡面的實現有可能是用多線程或者是非同步任務去做的,這就會導致咱們期望函數回調完畢去返回一個主函數的結果,實際發現是行不通的,因為如果回調是多線程的話是無法和主函數同步的,也就是返回的數據是錯誤的,這是非常隱秘的一個錯誤。那有什麼好的方法去實現數據的線性傳遞呢?先介紹下回調機制原理。
回調函數
回調函數就是一個通過函數指針調用的函數。如果把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用為調用它所指向的函數時,咱們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用於對該事件或條件進行響應。
開發中,介面回調是經常用到的。
介面回調的意思即,注冊之後並不立馬執行,而在某個時機觸發執行。
舉個例子:
A有一個問題不會,他去問B,B暫時解決不出來,B說,等咱(B)解決了再告訴(A)此時A可以繼續先做別的事情。
那麼就只有當B解決完問題後告訴A問題解決了,A才可以能解決這個問題。
代碼中比如最常用的:
一個Activity中給按鈕一個介面回調方法,只有用戶點擊了這個按鈕,告訴按鈕被點擊了,才會執行按鈕介面回調的方法

Button btn = new Button(this);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

}
});

那麼下面通過一個Demo理解介面回調:
主線程開啟一個非同步任務,當非同步任務接收到數據,則把數據用TextView顯示出來
1、首先 咱們需要定義一個介面,定義一個方法,參數為一個字元串:

package com.xqx.InterfaceDemo;
public interface ChangeTitle {
void onChangeTitle(String title);
}

2、寫一個非同步任務,把介面作為構造方法參數,在doInBackground()方法中判斷如果有數據,則介面回調

package com.xqx.InterfaceDemo;
import android.content.Context;
import android.os.AsyncTask;
public class MyTask extends AsyncTask<String,Void,String>{
private ChangeTitle changeTitle;
public MyTask(ChangeTitle changeTitle) {
this.changeTitle = changeTitle;
}
@Override
protected String doInBackground(String... strings) {
if (strings[0]!=null){
changeTitle.onChangeTitle(strings[0]);
}
return null;
}
}

3、主Activity,給非同步任務參數傳this,即 介面回調方法在此類中執行,那麼就需要實現ChangeTitle介面,重寫介面中
onChangeTitle 方法

package com.xqx.InterfaceDemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity implements ChangeTitle {
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView) findViewById(R.id.textView);
new MyTask(this).execute("我是標題");
}
// 重寫介面方法,執行相應操作
@Override
public void onChangeTitle(String title) {
textView.setText(title);
}
}

⑻ android自定義控制項怎麼用

一、控制項自定義屬性介紹
以下示例中代碼均在values/attrs.xml 中定義,屬性均可隨意命名。
1. reference:參考某一資源ID。
示例:
<declare-styleable name = "名稱">

<attr name = "background" format = "reference" />
<attr name = "src" format = "reference" />
</declare-styleable>

2. color:顏色值。
示例:
<declare-styleable name = "名稱">

<attr name = "textColor" format = "color" />
</declare-styleable>

3. boolean:布爾值。
示例:
<declare-styleable name = "名稱">

<attr name = "focusable" format = "boolean" />
</declare-styleable>

4. dimension:尺寸值。
示例:
<declare-styleable name = "名稱">

<attr name = "layout_width" format = "dimension" />
</declare-styleable>

5. float:浮點值。
示例:
<declare-styleable name = "名稱">

<attr name = "fromAlpha" format = "float" />
<attr name = "toAlpha" format = "float" />
</declare-styleable>

6. integer:整型值。
示例:
<declare-styleable name = "名稱">

<attr name = "frameDuration" format="integer" />
<attr name = "framesCount" format="integer" />
</declare-styleable>

7. string:字元串。
示例:
<declare-styleable name = "名稱">

<attr name = "text" format = "string" />
</declare-styleable>

8. fraction:百分數。
示例:

<declare-styleable name="名稱">
<attr name = "pivotX" format = "fraction" />
<attr name = "pivotY" format = "fraction" />
</declare-styleable>

9. enum:枚舉值。
示例:
<declare-styleable name="名稱">

<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
</declare-styleable>

10. flag:位或運算。
示例:
<declare-styleable name="名稱">

<attr name="windowSoftInputMode">
<flag name = "stateUnspecified" value = "0" />
<flag name = "stateUnchanged" value = "1" />
<flag name = "stateHidden" value = "2" />
<flag name = "stateAlwaysHidden" value = "3" />
</attr>
</declare-styleable>

11.多類型。
示例:

<declare-styleable name = "名稱">
<attr name = "background" format = "reference|color" />
</declare-styleable>

二、屬性的使用以及自定義控制項的實現
1、構思控制項的組成元素,思考所需自定義的屬性。
比如:我要做一個 <帶陰影的按鈕,按鈕正下方有文字說明>(類似9宮格按鈕)
新建values/attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="custom_view">
<attr name="custom_id" format="integer" />
<attr name="src" format="reference" />
<attr name="background" format="reference" />
<attr name="text" format="string" />
<attr name="textColor" format="color" />
<attr name="textSize" format="dimension" />
</declare-styleable>
</resources>

以上,所定義為custom_view,custom_id為按鈕id,src為按鈕,background為陰影背景,text為按鈕說明,textColor為字體顏色,textSize為字體大小。

2、怎麼自定義控制項呢,怎麼使用這些屬性呢?話不多說請看代碼,CustomView :

package com.nanlus.custom;
import com.nanlus.custom.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomView extends FrameLayout implements OnClickListener {
private CustomListener customListener = null;
private Drawable mSrc = null, mBackground = null;
private String mText = "";
private int mTextColor = 0;
private float mTextSize = 20;
private int mCustomId = 0;
private ImageView mBackgroundView = null;
private ImageButton mButtonView = null;
private TextView mTextView = null;
private LayoutParams mParams = null;
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.custom_view);
mSrc = a.getDrawable(R.styleable.custom_view_src);
mBackground = a.getDrawable(R.styleable.custom_view_background);
mText = a.getString(R.styleable.custom_view_text);
mTextColor = a.getColor(R.styleable.custom_view_textColor,
Color.WHITE);
mTextSize = a.getDimension(R.styleable.custom_view_textSize, 20);
mCustomId = a.getInt(R.styleable.custom_view_custom_id, 0);
mTextView = new TextView(context);
mTextView.setTextSize(mTextSize);
mTextView.setTextColor(mTextColor);
mTextView.setText(mText);
mTextView.setGravity(Gravity.CENTER);
mTextView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
mButtonView = new ImageButton(context);
mButtonView.setImageDrawable(mSrc);
mButtonView.setBackgroundDrawable(null);
mButtonView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
mButtonView.setOnClickListener(this);
mBackgroundView = new ImageView(context);
mBackgroundView.setImageDrawable(mBackground);
mBackgroundView.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
addView(mBackgroundView);
addView(mButtonView);
addView(mTextView);
this.setOnClickListener(this);
a.recycle();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mParams = (LayoutParams) mButtonView.getLayoutParams();
if (mParams != null) {
mParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
mButtonView.setLayoutParams(mParams);
}
mParams = (LayoutParams) mBackgroundView.getLayoutParams();
if (mParams != null) {
mParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
mBackgroundView.setLayoutParams(mParams);
}
mParams = (LayoutParams) mTextView.getLayoutParams();
if (mParams != null) {
mParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
mTextView.setLayoutParams(mParams);
}
}
public void setCustomListener(CustomListener l) {
customListener = l;
}
@Override
public void onClick(View v) {
if (customListener != null) {
customListener.onCuscomClick(v, mCustomId);
}
}
public interface CustomListener {
void onCuscomClick(View v, int custom_id);
}
}
代碼很簡單,就不多說,下面來看看我們的CustomView是怎麼用的,請看:

3、自定義控制項的使用
話不多說,請看代碼,main.xml:
<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:nanlus="http://schemas.android.com/apk/res/com.nanlus.custom"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:orientation="horizontal" >
<com.nanlus.custom.CustomView
android:id="@+id/custom1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
nanlus:background="@drawable/background"
nanlus:custom_id="1"
nanlus:src="@drawable/style_button"
nanlus:text="按鈕1" >
</com.nanlus.custom.CustomView>
</LinearLayout>
</RelativeLayout>

在這里需要解釋一下,
xmlns:nanlus="http://schemas.android.com/apk/res/com.nanlus.custom"
nanlus為在xml中的前綴,com.nanlus.custom為包名

4、在Activity中,直接上代碼
package com.nanlus.custom;

import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.nanlus.BaseActivity;
import com.nanlus.custom.R;
import com.nanlus.custom.CustomView.CustomListener;
public class CustomActivity extends BaseActivity implements CustomListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((CustomView) this.findViewById(R.id.custom1)).setCustomListener(this);
}
@Override
public void onCuscomClick(View v, int custom_id) {
switch (custom_id) {
case 1:
Toast.makeText(this, "hello !!!", Toast.LENGTH_LONG).show();
break;
default:
break;
}
}
}

⑼ Android怎麼定義回調函數

class
a
implements
camera.previewcallback{
/**
*
預覽幀回調函數
*
*/
public
void
onpreviewframe(byte[]
data,
camera
camera)
{
//當視頻流開啟的時候就可以在這個方法里做你想做的事,那麼這個就是一個回調函數
}
}

⑽ android代碼中,什麼時候需要自定義回調函數

當你想要把具體的操作,讓具體的人來完成,自己定義一個介面就好。使用的時候用介面,具體的人來實現你的介面,也就是實現了回調。

熱點內容
密碼輸入多少次會鎖 發布:2025-04-23 04:53:00 瀏覽:65
文件夾加固 發布:2025-04-23 04:52:11 瀏覽:914
android消息傳遞 發布:2025-04-23 04:50:45 瀏覽:796
sky伺服器錯誤什麼意思 發布:2025-04-23 04:50:02 瀏覽:379
三星usb存儲設備在哪 發布:2025-04-23 04:43:31 瀏覽:498
把什麼塗在密碼鎖上能看到密碼 發布:2025-04-23 04:29:40 瀏覽:242
sql2000密碼忘記 發布:2025-04-23 04:22:03 瀏覽:21
安卓手機退出應用怎麼絲滑 發布:2025-04-23 04:17:46 瀏覽:107
小米全盤加密 發布:2025-04-23 04:14:24 瀏覽:741
pac腳本代理伺服器地址 發布:2025-04-23 04:08:44 瀏覽:954