2012-05-17 27 views
2

我正在嘗試爲應用程序實現應用內結算。Android應用內結算:空指針異常

我在閱讀developer.android.com上的指南,查看他們的示例應用程序。

我開始是否支持應用內結算來寫支票的基本方法,但是當我嘗試調用sendBillingRequest我收到以下錯誤:

05-17 14:23:30.479: W/System.err(15332): java.lang.NullPointerException 
05-17 14:23:30.489: W/System.err(15332): at resistorcalc.main.billing.BillingService.checkBilling(BillingService.java:63) 
05-17 14:23:30.489: W/System.err(15332): at resistorcalc.main.SupportusActivity.onCreate(SupportusActivity.java:24) 
05-17 14:23:30.499: W/System.err(15332): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
05-17 14:23:30.509: W/System.err(15332): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615) 
05-17 14:23:30.509: W/System.err(15332): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667) 
05-17 14:23:30.519: W/System.err(15332): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 
05-17 14:23:30.529: W/System.err(15332): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) 
05-17 14:23:30.539: W/System.err(15332): at android.os.Handler.dispatchMessage(Handler.java:99) 
05-17 14:23:30.539: W/System.err(15332): at android.os.Looper.loop(Looper.java:130) 
05-17 14:23:30.549: W/System.err(15332): at android.app.ActivityThread.main(ActivityThread.java:3687) 
05-17 14:23:30.549: W/System.err(15332): at java.lang.reflect.Method.invokeNative(Native Method) 
05-17 14:23:30.549: W/System.err(15332): at java.lang.reflect.Method.invoke(Method.java:507) 
05-17 14:23:30.549: W/System.err(15332): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
05-17 14:23:30.559: W/System.err(15332): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 
05-17 14:23:30.559: W/System.err(15332): at dalvik.system.NativeStart.main(Native Method) 

的BillingService有類是:

package resistorcalc.main.billing; 

import android.app.Service; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.os.RemoteException; 
import android.util.Log; 

import com.android.vending.billing.IMarketBillingService; 

public class BillingService extends Service implements ServiceConnection { 


private static final String TAG = "BillingService"; 
private IMarketBillingService mService; 

public BillingService(){ 
    super(); 
} 

@Override 
public void onCreate() {   
    super.onCreate(); 
    try { 
     Log.i(TAG, "Service starting with onCreate");    
     boolean bindResult = bindService(new Intent("com.android.vending.billing.MarketBillingService.BIND"), this, Context.BIND_AUTO_CREATE); 
     if(bindResult){ 
      Log.i(TAG,"Market Billing Service Successfully Bound"); 
     } else { 
      Log.e(TAG,"Market Billing Service could not be bound.");    
     } 
    } catch (SecurityException e){ 
       Log.e(TAG,"Market Billing Service could not be bound. SecurityException: "+e);     
    }  
} 

public void setContext(Context context) { 
    attachBaseContext(context); 
} 

/** 
    * The Android system calls this when we are connected to the MarketBillingService. 
    */ 
public void onServiceConnected(ComponentName name, IBinder service) { 
    Log.i(TAG, "MarketBillingService connected."); 
    mService = IMarketBillingService.Stub.asInterface(service); 
} 

protected Bundle makeRequestBundle(String method) { 
    Bundle request = new Bundle(); 
    request.putString(BillingConst.BILLING_REQUEST_METHOD, method); 
    request.putInt(BillingConst.BILLING_REQUEST_API_VERSION, 1); 
    request.putString(BillingConst.BILLING_PACKAGE_NAME, getPackageName()); 
    return request; 
} 

public boolean checkBilling(){  
    try { 
     Bundle request = makeRequestBundle("CHECK_BILLING_SUPPORTED"); 
     Bundle response = mService.sendBillingRequest(request); 
     int code = response.getInt("RESPONSE_CODE"); 
     if(code==0){ 
      return true; 
     } else { 
      return false; 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
     System.err.print(e.getMessage()); 
     return false; 
    } 
} 

public void onServiceDisconnected(ComponentName arg0) { 
    // TODO Auto-generated method stub 

} 

@Override 
public IBinder onBind(Intent arg0) { 
    // TODO Auto-generated method stub 
    return null; 
} 

}

的異常發生在該行:

Bundle response = mService.sendBillingRequest(request);

發生這種情況是因爲mService變量爲空。該MSERVICE變量被初始化在該方法:

public void onServiceConnected(ComponentName name, IBinder service) { 
    Log.i(TAG, "MarketBillingService connected."); 
    mService = IMarketBillingService.Stub.asInterface(service); 
} 

(如寫在該指南:http://developer.android.com/guide/market/billing/billing_integrate.html#billing-service) 的問題是,onServiceConnected永遠不會調用。

該推出的服務活動:

public void onCreate(Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.supportus); 
    mBillingService = new BillingService(); 
    mBillingService.setContext(this); 
    Intent intent = new Intent(); 
      intent.setClass(this, BillingService.class);   
    startService(intent); 
    if(mBillingService.checkBilling()){ 
     Toast.makeText(this, "TRUE", Toast.LENGTH_SHORT); 
    } else { 
     Toast.makeText(this, "FALSE", Toast.LENGTH_SHORT); 
    } 
} 

我不明白是什麼問題。爲什麼不調用onCreate和onServiceConnected方法?查看服務生命週期時,應使用startService調用BillingService onCreate方法。 我錯在哪裏

+0

我認爲你的日誌不完整。沒有看到任何nullpointerexception。 – keyser

+0

ops抱歉,剛拷貝了錯誤的部分。固定。 – Ivan

回答

1

最後我找到了解決這個問題的方法。這是我的錯。

錯誤是在清單中,其實我在服務聲明爲

<service android:name=".BillingService" /> 

但BillingService有類是在一個子包(resistorcalc.main.billing)。然後我用下面這行代替:

<service android:name=".billing.BillingService" /> 

服務開始工作。

+0

您不應該將這樣的答案標記爲「正確」。這本身就是你的問題,不會幫助任何人。我只是認爲這不是一個真正的產生SO聲譽的方法。 –

+0

所以可能你不知道,當你接受自己的答案時,你沒有獲得任何積分? – Ivan

1

在嘗試使用mService之前未調用onServiceConnected()。這是因爲你的activity的onServiceConnected()方法在onCreate()返回之前是不能被調用的,它尚未完成。

基本上你需要在服務連接後再打電話給checkBilling()。您可能會響應服務連接來做到這一點,或者您可能會在用戶實際嘗試執行某些操作時執行此操作。