以编程方式添加按钮的问题

时间:2014-08-10 21:44:49

标签: android onclicklistener

实际上我以编程方式添加一些按钮没有任何问题。之后我需要重新创建按钮并删除旧按钮。我也为每个按钮设置了OnClickListener。我的问题是,当我回想起funcrion refresh()并重新创建按钮,按钮成功添加,但当我点击按钮,程序崩溃! :|

      Main Class:

package com.example.mysqlex;

import com.example.mysqlex.DbHandler;
import com.example.mysqlex.DbHelper;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import android.content.Context;

@SuppressLint("ResourceAsColor")
public class Main extends Activity {
static String Totalresult;
static LinearLayout Llayout,mainRel;
static TextView titleTest;
private static Context context;
private Typeface font;


private DbHandler dbHandler=new DbHandler(this);
public DbHelper dbHelper=new DbHelper(this);
private SQLiteDatabase database;

public static boolean haveNetworkConnection() {
    boolean haveConnectedWifi = false;
    boolean haveConnectedMobile = false;

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo[] netInfo = cm.getAllNetworkInfo();
    for (NetworkInfo ni : netInfo) {
        if (ni.getTypeName().equalsIgnoreCase("WIFI"))
            if (ni.isConnected())
                haveConnectedWifi = true;
        if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
            if (ni.isConnected())
                haveConnectedMobile = true;
    }
    return haveConnectedWifi || haveConnectedMobile;
}
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); 
    mainRel=(LinearLayout) findViewById(R.id.mainRel);
    Typeface font = Typeface.createFromAsset(getAssets(),"fonts/yekan2.TTF");
    TextView title=(TextView) findViewById(R.id.title);
    title.setTypeface(font);
    context=this;
    if(dbHandler.getSettings("catlist", "value")=="null"){
        Toast.makeText(getApplicationContext(), "اطلاعاتی ذخیره نشده است.لطفا نوسازی کنید...", 5000).show();
    }else{
        refresh("home");
    }
}
public void refresh(String refreshType){
    dbHandler=new DbHandler(context);
    dbHelper=new DbHelper(context);
    if(refreshType=="button"){
        if(dbHandler.getSettings("catlist", "value")=="null"){
            dbHandler.insertSettings("catlist", Totalresult, "");
        }else{
            dbHandler.updateSettings("catlist", Totalresult, "");
        }
    }else if(refreshType=="home"){
        Totalresult=dbHandler.getSettings("catlist", "value");
    }
    Typeface font = Typeface.createFromAsset(context.getAssets(),"fonts/yekan2.TTF");
    String[] childs=Totalresult.split("/.../<br />");
    mainRel.removeAllViews();

    for(int i=0; i<childs.length; i++){
        String[] parts=childs[i].split("<br />");
        final String[] values=parts[1].split("->");

        final String[] id=parts[0].split("->");

        Button btn = new Button(context);
        LinearLayout Llayout = new LinearLayout(context);
        btn.setBackgroundResource(R.drawable.cat_drawable);
        btn.setHeight(110); btn.setTextSize(24); btn.setTypeface(font); btn.setTextColor(R.color.white);
        btn.setId(i);
        btn.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            Intent goToContent = new Intent(Main.this, Content.class); 
            goToContent.putExtra("catid", id[1]);
            goToContent.putExtra("pageTitle", values[1]);
            startActivity(goToContent);
        }
    });

        LayoutParams btnLp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
        LinearLayout.LayoutParams LLp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);

        LLp.setMargins(0, 5, 0, 5);
        btn.setLayoutParams(btnLp);
        Llayout.setLayoutParams(LLp);

        btn.setText(values[1]);
        Llayout.addView(btn);
        mainRel.addView(Llayout);
    }
}
public void refresh_btn(View v) {
    if(haveNetworkConnection()){
        SigninActivity.classReferrer="Main";
        new SigninActivity(this,0).execute("site_id","1","catlist","1","data_type","echo(/.../)");
    }else{
        Toast.makeText(getApplicationContext(), "لطفا جهت نوسازی اطلاعات،به اینترنت متصل شوید", Toast.LENGTH_LONG).show();
    }
  }
}


   SigninActivity Class :
package com.example.mysqlex;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.ref.WeakReference;
import java.lang.reflect.Array;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;


import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.TextView;
import android.widget.Toast;

public class SigninActivity  extends AsyncTask<String,Void,String>{
private ProgressDialog pdia;
String url="http://www.pbroilgas.com/index2.php";
private TextView roleField;
private Context context;
private int byGetOrPost = 0; 
static public String results,classReferrer;
static public String[] resultArray;
//flag 0 means get and 1 means post.(By default it is get.)
public SigninActivity(Context context,int flag) {
  this.context = context;
  byGetOrPost = flag;
}

protected void onPreExecute(){

   pdia = new ProgressDialog(context);
   pdia.setMessage("در حال نوسازی اطلاعات...");
   pdia.setProgressStyle(pdia.STYLE_SPINNER);
   pdia.show();
   super.onPreExecute();
}
@Override
protected String doInBackground(String... arg0) {
  if(byGetOrPost == 0){ //means by Get Method
     try{
         String command1 = (String)arg0[0];
         String value1 = (String)arg0[1];
         StringBuilder link = new StringBuilder();
         link.append(url+"?"+command1+"="+value1);
         for(int i=2; i<arg0.length; i+=2){
             link.append("&"+arg0[i]);
             link.append("="+arg0[i+1]);
         }
        URL url = new URL(link.toString());
        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet();
        request.setURI(new URI(link.toString()));
        HttpResponse response = client.execute(request);
        BufferedReader in = new BufferedReader
       (new InputStreamReader(response.getEntity().getContent()));

       StringBuffer sb = new StringBuffer("");
       String line;
       while ((line = in.readLine()) != null) {
           sb.append(line);
        }
        in.close();
        return sb.toString();
  }catch(Exception e){
     return new String("Exception: " + e.getMessage());
  }
  }
  else{
     try{
        String command = (String)arg0[0];
        String value = (String)arg0[1];
        String link=url;
        String data  = URLEncoder.encode(command, "UTF-8") 
        + "=" + URLEncoder.encode(value, "UTF-8");
        URL url = new URL(link);
        URLConnection conn = url.openConnection(); 
        conn.setDoOutput(true); 
        OutputStreamWriter wr = new OutputStreamWriter
        (conn.getOutputStream()); 
        wr.write( data ); 
        wr.flush(); 
        BufferedReader reader = new BufferedReader
        (new InputStreamReader(conn.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line = null;
        // Read Server Response
        while((line = reader.readLine()) != null)
        {
           sb.append(line);
           break;
        }
        return sb.toString();
     }catch(Exception e){
        return new String("Exception: " + e.getMessage());
     }
  }
}

@Override
protected void onPostExecute(String result){
   pdia.dismiss();
   results=result;
   if(classReferrer=="Main"){
       Main  main= new Main();
       Main.Totalresult=result.toString();
       main.refresh("button");
   }else if(classReferrer=="Content"){
       Content  content= new Content();
       Content.Totalresult=result.toString();
       content.refresh("button");
   }
  }
}

我的LogCat: 08-11 02:12:55.839: E/AndroidRuntime(8853): FATAL EXCEPTION: main 08-11 02:12:55.839: E/AndroidRuntime(8853): java.lang.NullPointerException 08-11 02:12:55.839: E/AndroidRuntime(8853): at android.content.ContextWrapper.getPackageName(ContextWrapper.java:127) 08-11 02:12:55.839: E/AndroidRuntime(8853): at android.content.ComponentName.<init>(ComponentName.java:75) 08-11 02:12:55.839: E/AndroidRuntime(8853): at android.content.Intent.<init>(Intent.java:3350) 08-11 02:12:55.839: E/AndroidRuntime(8853): at com.example.mysqlex.Main$1.onClick(Main.java:99) 08-11 02:12:55.839: E/AndroidRuntime(8853): at android.view.View.performClick(View.java:4147) 08-11 02:12:55.839: E/AndroidRuntime(8853): at android.view.View$PerformClick.run(View.java:17161) 08-11 02:12:55.839: E/AndroidRuntime(8853): at android.os.Handler.handleCallback(Handler.java:615) 08-11 02:12:55.839: E/AndroidRuntime(8853): at android.os.Handler.dispatchMessage(Handler.java:92) 08-11 02:12:55.839: E/AndroidRuntime(8853): at android.os.Looper.loop(Looper.java:213) 08-11 02:12:55.839: E/AndroidRuntime(8853): at android.app.ActivityThread.main(ActivityThread.java:4786) 08-11 02:12:55.839: E/AndroidRuntime(8853): at java.lang.reflect.Method.invokeNative(Native Method) 08-11 02:12:55.839: E/AndroidRuntime(8853): at java.lang.reflect.Method.invoke(Method.java:511) 08-11 02:12:55.839: E/AndroidRuntime(8853): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 08-11 02:12:55.839: E/AndroidRuntime(8853): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) 08-11 02:12:55.839: E/AndroidRuntime(8853): at dalvik.system.NativeStart.main(Native Method) 我很感激你的帮助...... 提前谢谢......

2 个答案:

答案 0 :(得分:1)

错误表明它无法获取包名称。所以你的Main.this由于某种原因在那时是无效的。将其更改为:

    public void onClick(View arg0) {
        Intent goToContent = new Intent(arg0.getContext(), Content.class);
        goToContent.putExtra("catid", id[1]);
        goToContent.putExtra("pageTitle", values[1]);
        startActivity(goToContent);
    }

您的上下文引用无效,但调用该方法的视图永远不会无效。

答案 1 :(得分:0)

查看Intent(Context, Class<?>) ...

的来源
public Intent(Context packageContext, Class<?> cls) {
    mComponent = new ComponentName(packageContext, cls);
}

...然后查看ComponentName(Context, Class<?>)构造函数的源代码......

public ComponentName(Context pkg, Class<?> cls) {
    mPackage = pkg.getPackageName();
    mClass = cls.getName();
}

...使用Intent(Context, Class<?>)投放NPE的唯一方法是mPackage = pkg.getPackageName(); - 换句话说,Main.this为空。

查看更新的代码,我可以看到原因。在您onPostExecute(...)的{​​{1}}的{​​{1}}中,您正在执行以下操作...

AsyncTask

无法使用SigninActivity创建Main main= new Main(); 的实例 - 它根本不起作用,这就是Activitynew的原因。

您将不得不重新考虑事情,因为您永远不应尝试从任何其他应用程序组件访问Main.this的任何变量或方法。

如果您需要从null访问Activity中的方法,最简单的方法是使Activity成为AsyncTask本身的内部类。