아래 소스는요....
채팅프로그램을 연습하고 있는 소스입니다.,...
그런데 이게... 안되더군요 ㅠㅠ
문제는 adapter의 위치를 어떻게 넣어야 하느냐... 인 것 같습니다만... 전혀 감이 잡히지를 않습니다 ㅠㅠ
안드로이드 시작한지 한달이나 돼가는데 ㅠㅠ 막막하기만 한에요 ㅠㅠ
도와주시면 감사드리겠습니다... ㅠㅠ
----------------------------------------------------------------------------------------------------
//지금 xml은 tvResult를 visible = gone 이구요 Scroll도 visible gone 입니다....
// 대체 adapter를 어디다가 넣어야 할지를 모르겠어요 ㅠㅠ 부탁드리겠습니다 ㅠㅠ
package com.example.messinger_ato;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
public class Messinger_ATO extends Activity implements OnClickListener, Runnable {
Thread m_thread;
boolean m_bRun;
Socket m_socket;
BufferedReader reader;
PrintWriter writer;
TextView tvResult;
ListView list;
ScrollView scroll;
StringBuffer sb= new StringBuffer();;
int m_isSendDirection = 1;
int m_isRecvDirection = 2;
MyAdapter adapter;
ArrayList<MyData> arrList;
int direction;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messinger__ato);
findViewById(R.id.insert_button).setOnClickListener(this);
tvResult = (TextView)findViewById(R.id.ChattingScreen);
scroll = (ScrollView)findViewById(R.id.scrollView);
list = (ListView)findViewById(R.id.list); // 되던 소스에서 이부분은 추가했습니다.
start();
adapter = new MyAdapter(context, arrList); //되던 소스에서 이부분은 추가했습니다.
// 이 adapter만 지워버리면 소스는 잘 돌아가는대신에... 이에 대해서는 아무런 반응을 하지를 않습니다 ㅠㅠ
list.setAdapter(adapter);
}
@Override
public void onDestroy()
{
stop();
super.onDestroy();
}
Context context = this.getBaseContext();
public void addResult(final String msg)
{
list.post(new Runnable()
{
public void run()
{
ArrayList<MyData> arrList = new ArrayList<MyData>();
//MyData md = new MyData(sb.toString(), direction);
sb.append(msg);
sb.append("\n");
arrList.add(new MyData(sb.toString(), 1));
//원래는 tvResult.setText(sb.toString()); 으로 했구요 이거는 먹혔습니다. 하지만 이부분은 Sorry 에러에 영향을 주지 않았습니다.
adapter.notifyDataSetChanged();
// 이것도... 처음에는 갱신하는 객체가 있었나... 하다가 방금전에 알아낸건데... 이걸 써두 안되더라구요 ㅎㅎ;;
//이것은 처음에 list.setAdapter(adapter); 소스로 사용했는데.... adpater가 정의되지 않았을 때에는 Sorry 에러에 영향을 주지 않았습니다.
}
}
);
}
@Override
public void run()
{
try {
m_socket = new Socket("xxx.xxx.xxx.xxx", xxxx);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
InputStream is = null;
OutputStream os = null;
try {
is = m_socket.getInputStream();
os = m_socket.getOutputStream();
reader = new BufferedReader(new InputStreamReader(is, "euc-kr"));
writer = new PrintWriter(new OutputStreamWriter(os, "euc-kr"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
m_bRun = true;
while( m_bRun )
{
String msg = null;
try {
msg = reader.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
break;
}
if( null == msg ) break;
addResult(msg);
}
try {
m_socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
m_socket = null;
addResult("Disconnected");
}
int msgType;
@Override
public void onClick(View v) {
switch(v.getId())
{
case R.id.insert_button:
if( null == m_thread )
{
addResult("Not connected yet");
return;
}
else
{
EditText etChat = (EditText)findViewById(R.id.insert_text);
String msg = etChat.getText().toString();
writer.println(msg);
writer.flush();
etChat.setText("");
addResult(msg + "\n");
}
scroll.fullScroll(View.FOCUS_DOWN);
break;
}
}
public void start()
{
if( null != m_thread ) stop();
m_thread = new Thread(this);
m_thread.start();
addResult("Connected \n");
}
public void stop()
{
if( null == m_thread ) return;
try {
m_socket.shutdownOutput();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
m_bRun = false;
try {
m_thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("stop", "stopped");
m_thread = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_messinger__ato, menu);
return true;
}
}
--------------------------------------------------------------------------------------------------
Messinger_ATO.java
추가로 다른 소스들까지 써드립니다 ㅠㅠ
--------------------------------------------------------------------------------------------------
package com.example.messinger_ato;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter {
Context context;
LayoutInflater inflater;
private ArrayList<MyData> arrList;
public MyAdapter(Context c, ArrayList<MyData> arr)
{
this.context = c;
this.arrList = arr;
inflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
// TODO Auto-generated method stub
return arrList.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return arrList.get(position).m_message;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
TextView textMessage;
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
int Direction = 0;
int sendDirection = 1;
int recvDirection = 2;
int dataDirection = arrList.get(position).getDirection();
if(convertView == null)
{
convertView = inflater.inflate(R.layout.list_layout, parent, false);
}
//----------------------- Direction 방향에 따라서...--------------------------------------
if(Direction == 0)
{
Direction = dataDirection;
}
if(Direction == sendDirection){
textMessage = (TextView)convertView.findViewById(R.id.sendMessage);
Direction = 0;
}
if(Direction == recvDirection)
{
textMessage = (TextView)convertView.findViewById(R.id.recvMessage);
Direction = 0;
}
//---------------------------------------------------------------------------------------
textMessage.setText(arrList.get(position).getMessage());
return convertView;
}
}
--------------------------------------------------------------------------------------------------
MyAdapter.java
--------------------------------------------------------------------------------------------------
package com.example.messinger_ato;
public class MyData {
String m_message;
int m_direction;
public MyData(String message, int direction)
{
this.m_message = message;
this.m_direction = direction;
}
public String getMessage()
{
return m_message;
}
public int getDirection()
{
return m_direction;
}
}
--------------------------------------------------------------------------------------------------
MyData.java
부탁드립니다 ㅠㅠㅠㅠㅠㅠ
추가로 로그캣도 올려요 ㅠㅠ
--------------------------------------------------------------------------------------------------
07-23 07:26:25.979: D/AndroidRuntime(2592): Shutting down VM
07-23 07:26:25.989: W/dalvikvm(2592): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
07-23 07:26:26.011: E/AndroidRuntime(2592): FATAL EXCEPTION: main
07-23 07:26:26.011: E/AndroidRuntime(2592): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.messinger_ato/com.example.messinger_ato.Messinger_ATO}: java.lang.NullPointerException
07-23 07:26:26.011: E/AndroidRuntime(2592): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
07-23 07:26:26.011: E/AndroidRuntime(2592): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
07-23 07:26:26.011: E/AndroidRuntime(2592): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
07-23 07:26:26.011: E/AndroidRuntime(2592): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
07-23 07:26:26.011: E/AndroidRuntime(2592): at android.os.Handler.dispatchMessage(Handler.java:99)
07-23 07:26:26.011: E/AndroidRuntime(2592): at android.os.Looper.loop(Looper.java:123)
07-23 07:26:26.011: E/AndroidRuntime(2592): at android.app.ActivityThread.main(ActivityThread.java:4627)
07-23 07:26:26.011: E/AndroidRuntime(2592): at java.lang.reflect.Method.invokeNative(Native Method)
07-23 07:26:26.011: E/AndroidRuntime(2592): at java.lang.reflect.Method.invoke(Method.java:521)
07-23 07:26:26.011: E/AndroidRuntime(2592): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-23 07:26:26.011: E/AndroidRuntime(2592): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-23 07:26:26.011: E/AndroidRuntime(2592): at dalvik.system.NativeStart.main(Native Method)
07-23 07:26:26.011: E/AndroidRuntime(2592): Caused by: java.lang.NullPointerException
07-23 07:26:26.011: E/AndroidRuntime(2592): at com.example.messinger_ato.MyAdapter.<init>(MyAdapter.java:23)
07-23 07:26:26.011: E/AndroidRuntime(2592): at com.example.messinger_ato.Messinger_ATO.onCreate(Messinger_ATO.java:57)
07-23 07:26:26.011: E/AndroidRuntime(2592): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
07-23 07:26:26.011: E/AndroidRuntime(2592): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
07-23 07:26:26.011: E/AndroidRuntime(2592): ... 11 more
07-23 07:26:26.029: I/global(2592): Default buffer size used in BufferedReader constructor. It would be better to be explicit if an 8k-char buffer is required.
07-23 07:26:26.011: E/AndroidRuntime(2592): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.messinger_ato/com.example.messinger_ato.Messinger_ATO}: java.lang.NullPointerException
Null 포인터 문제네요.
onCreate() 당시에 어댑터로 넘겨주는 arrList가 초기화되지 않아서 null이 넘어갔을 것이며,
당연히 사용시에 문제가 되겠죠.
ArrayList<MyData> arrList = new ArrayList<MyData>();
이 코드는
adapter = new MyAdapter(context, arrList);
이 코드 전에 실행되어야 합니다.
list view에서 사용목적이니 만큼 클래스 변수로 올리시는 것을 추천드립니다.