Java 线程问题:NullPointerException
当我试图将listView最后一项中的文本设置为MainActivity中的文本视图时,出现了一个问题。它在运行“NullPointerException”时崩溃,因为我认为在MainActivity中调用它时,它没有完成在ListView上的下载,所以当MainActivity首次启动时,ListView没有完成他的工作,函数getCount()、getItem()和我的函数getLastElement()仍然为null。 问题是我不太擅长处理线程(Wait(),notify(),…) 你能帮我做这一切吗 这是我的代码和日志:Java 线程问题:NullPointerException,java,android,multithreading,listview,nullpointerexception,Java,Android,Multithreading,Listview,Nullpointerexception,当我试图将listView最后一项中的文本设置为MainActivity中的文本视图时,出现了一个问题。它在运行“NullPointerException”时崩溃,因为我认为在MainActivity中调用它时,它没有完成在ListView上的下载,所以当MainActivity首次启动时,ListView没有完成他的工作,函数getCount()、getItem()和我的函数getLastElement()仍然为null。 问题是我不太擅长处理线程(Wait(),notify(),…) 你能帮
public class MainActivity extends Activity implements OnClickListener{
private static Context mContext;
public Button mExit, mHistory, mRating;
public TextView mSignal;
HistoryAdapt myAdapter;
HistoryItems m_myLastItem;
ArrayList<HistoryItems> m_myListItem;
Runnable m_run;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivity.mContext=getApplicationContext();
mExit=(Button)findViewById(R.id.ExitButton);
mExit.setOnClickListener(this);
mHistory=(Button)findViewById(R.id.HistoryButton);
mHistory.setOnClickListener(this);
mRating=(Button)findViewById(R.id.RateButton);
mRating.setOnClickListener(this);
mSignal=(TextView)findViewById(R.id.SignalOfTheDayTV);
//### SET LAST ELEMENT INTO TEXTVIEW
m_myListItem = new ArrayList<HistoryItems>();
myAdapter= new HistoryAdapt(mContext, m_myListItem);
new Thread(
new Runnable(){
@Override
public void run(){
try{
///Need to wait until the data to be downloaded inside HistoryAdapt so it can show the last element from the ListView here
HistoryParser parser = new HistoryParser();
parser.parse(getInputStream(HistoryAct.RSS_LINK));
} catch (XmlPullParserException e) {
Log.w(e.getMessage(), e);
} catch (IOException e) {
Log.w(e.getMessage(), e);
} finally {
//notify that the data finished to download
MainActivity.this.runOnUiThread(
new Runnable(){
public void run(){
m_myLastItem = myAdapter.getLastElement();
//set last signal into TextView
mSignal.setText(m_myLastItem.getTitle());
}
}
);
}
}
}
).run();
//#RATER
// AppRater.app_launched(this);
// AppRater.showRateDialog(this, null);
//Get a Tracker (should auto-report)
((AppManager) getApplication()).getTracker(AppManager.TrackerName.APP_TRACKER);
}//oncreate
private InputStream getInputStream(String link) {
try {
URL url = new URL(link);
return url.openConnection().getInputStream();
} catch (IOException e) {
Log.w(Constants.DATA, "Exception while retrieving the input stream", e);
return null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static Context getAppContext(){
return MainActivity.mContext;
}
public void ExitState(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("You're about to quit Signals4Trading");
builder.setIcon(R.drawable.five);
//builder.setMessage("Your device has been registered successfully. You'll receive signals very soon.");
builder.setMessage("Are you sure you want to quit?");
builder.setCancelable(false);//can't click on the background of the activity
builder.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),"See you soon", Toast.LENGTH_LONG).show();
finish();
}//OnClickListener PositiveButton
});//anonymous class PositiveButton
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),"Enjoy your visit", Toast.LENGTH_LONG).show();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}//ExitState
public void goToHistoryActivity(){
Intent intent = new Intent(MainActivity.this, HistoryAct.class );
startActivity(intent);
}
public void rateApp(){
Intent intent = new Intent(MainActivity.this, Rate.class);
startActivity(intent);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()){
case R.id.ExitButton:
ExitState();
break;
case R.id.HistoryButton:
goToHistoryActivity();
break;
case R.id.RateButton:
rateApp();
break;
}
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
//Get an Analytics tracker to report app starts & uncaught exceptions etc.
GoogleAnalytics.getInstance(this).reportActivityStart(this);
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
//Stop the analytics tracking
GoogleAnalytics.getInstance(this).reportActivityStop(this);
}
}//MainActivity
package com.Signals4Trading.push.android;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.os.StrictMode;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class HistoryAdapt extends BaseAdapter {
private final List<HistoryItems>items;
private final Context context;
public HistoryAdapt(Context context,List<HistoryItems>items){
this.context=context;
this.items=items;
}//constructor
@Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return items.get(position);
}
@Override
public long getItemId(int id) {
// TODO Auto-generated method stub
return id;
}
//###FUNCTION THAT RETURN LAST ELEMENT
public HistoryItems getLastElement(){
return items.get(items.size()-1);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(context, R.layout.historyitems, null);
holder = new ViewHolder();
holder.itemTitle = (TextView) convertView.findViewById(R.id.itemTitleTV);
holder.itemDate=(TextView) convertView.findViewById(R.id.itemDateTV);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.itemTitle.setText(items.get(position).getTitle());
holder.itemDate.setText(items.get(position).getDate());
}
return convertView;
}
class ViewHolder {
TextView itemTitle;
TextView itemDate;
}
}
//HistoryAdapt
11-13 15:18:34.702: E/AndroidRuntime(7737): FATAL EXCEPTION: main
11-13 15:18:34.702: E/AndroidRuntime(7737): Process: com.Signals4Trading.push.android, PID: 7737
11-13 15:18:34.702: E/AndroidRuntime(7737): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.Signals4Trading.push.android/com.Signals4Trading.push.android.MainActivity}:
java.lang.ArrayIndexOutOfBoundsException: length=0; index=-1
11-13 15:18:34.702: E/AndroidRuntime(7737): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
public类MainActivity扩展活动实现OnClickListener{
私有静态上下文mContext;
公共按钮mExit、mHistory、mRating;
公共文本视图mSignal;
历史适应;
历史项目m_myLastItem;
ArrayList m_Mylistem;
可运行的m_运行;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivity.mContext=getApplicationContext();
mExit=(按钮)findViewById(R.id.ExitButton);
mExit.setOnClickListener(this);
mHistory=(按钮)findViewById(R.id.HistoryButton);
mHistory.setOnClickListener(this);
mRating=(按钮)findviewbyd(R.id.RateButton);
mRating.setOnClickListener(此);
mSignal=(TextView)findViewById(R.id.signalOfDayTV);
//###将最后一个元素设置为TEXTVIEW
m_myListItem=新的ArrayList();
myAdapter=new HistoryAdapt(mContext,m_myListItem);
新线程(
新的Runnable(){
@凌驾
公开募捐{
试一试{
///需要等待HistoryAdapt中要下载的数据,以便在此处显示ListView中的最后一个元素
HistoryParser=新的HistoryParser();
parser.parse(getInputStream(HistoryAct.RSS_链接));
}catch(XMLPullParseRexE){
Log.w(e.getMessage(),e);
}捕获(IOE异常){
Log.w(e.getMessage(),e);
}最后{
//通知数据已完成下载
main activity.this.runOnUiThread(
新的Runnable(){
公开募捐{
m_myLastItem=myAdapter.getLastElement();
//将最后一个信号设置为文本视图
mSignal.setText(m_myLastItem.getTitle());
}
}
);
}
}
}
).run();
//#评分员
//apper.app_启动(本次);
//AppRater.showRateDialog(此为空);
//获取跟踪程序(应自动报告)
((AppManager)getApplication()).getTracker(AppManager.TrackerName.APP_TRACKER);
}//一次创建
私有InputStream getInputStream(字符串链接){
试一试{
URL=新的URL(链接);
返回url.openConnection().getInputStream();
}捕获(IOE异常){
Log.w(Constants.DATA,“检索输入流时异常”,e);
返回null;
}
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.main,menu);
返回true;
}
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
//处理操作栏项目单击此处。操作栏将
//自动处理Home/Up按钮上的点击,只要
//在AndroidManifest.xml中指定父活动时。
int id=item.getItemId();
if(id==R.id.action\u设置){
返回true;
}
返回super.onOptionsItemSelected(项目);
}
公共静态上下文getAppContext(){
返回MainActivity.mContext;
}
公共无效退出状态(){
AlertDialog.Builder=新建AlertDialog.Builder(此);
setTitle(“您将要退出Signals4Trading”);
builder.setIcon(R.drawable.5);
//setMessage(“您的设备已成功注册。您将很快收到信号。”);
setMessage(“您确定要退出吗?”);
builder.setCancelable(false);//无法单击活动的背景
builder.setPositiveButton(“是”,新建DialogInterface.OnClickListener(){
@凌驾
public void onClick(DialogInterface dialog,int which){
//TODO自动生成的方法存根
Toast.makeText(getApplicationContext(),“再见”,Toast.LENGTH_LONG.show();
完成();
}//onclick监听器正按钮
});//匿名类正按钮
setNegativeButton(“否”,新的DialogInterface.OnClickListener(){
@凌驾
public void onClick(DialogInterface dialog,int which){
//TODO自动生成的方法存根
Toast.makeText(getApplicationContext(),“祝您访问愉快”,Toast.LENGTH_LONG.show();
}
});
AlertDialog AlertDialog=builder.create();
alertDialog.show();
}//退出状态
公共无效goToHistoryActivity(){
意向意向=新意向(MainActivity.this、HistoryAct.class);
星触觉(意向);
}
公共应用程序()
Thread run = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
run = new Thread( new Runnable(){
public void run(){
if(!HistoryAdapt.hasBeenInitiated){
try {
///Need to wait until the data to be downloaded inside HistoryAdapt so it can show the last element from the ListView here
HistoryParser parser = new HistoryParser();
parser.parse(getInputStream(HistoryAct.RSS_LINK));
} catch (XmlPullParserException e) {
Log.w(e.getMessage(), e);
} catch (IOException e) {
Log.w(e.getMessage(), e);
}finally{
//notify that the data finished to download
}
}
}
});
run.start();
run.join();
m_myLastItem= HistoryAdapt.getLastElement();
new Thread(
new Runnable()
{
@Override
public void Run()
{
//your code here
}
}
).Run();
synchronized(this){
this = newvalue;
}
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
m_myLastItem = HistoryAdapt.getLastElement();
//set last signal into TextView
mSignal.setText(m_myLastItem.getTitle());
}
});
new Thread(
new Runnable()
{
@Override
public void run()
{
if(!HistoryAdapt.hasBeenInitiated)
{
try
{
///Need to wait until the data to be downloaded inside HistoryAdapt so it can show the last element from the ListView here
HistoryParser parser = new HistoryParser();
parser.parse(getInputStream(HistoryAct.RSS_LINK));
} catch (XmlPullParserException e) {
Log.w(e.getMessage(), e);
} catch (IOException e) {
Log.w(e.getMessage(), e);
} finally {
//notify that the data finished to download
MainActivity.this.runOnUiThread(
new Runnable()
{
public void run()
{
if (!HistoryAdapt.hasBeenInitiated)
{
m_myLastItem = HistoryAdapt.getLastElement();
//set last signal into TextView
mSignal.setText(m_myLastItem.getTitle());
}
}
}
);
}
}
}
}
).run();